You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@netbeans.apache.org by GitBox <gi...@apache.org> on 2022/08/25 10:43:10 UTC

[GitHub] [netbeans] MegJayan opened a new pull request, #4533: Implementation of auto completion, formatting adjustment and providing hints for JEP 405 record patterns

MegJayan opened a new pull request, #4533:
URL: https://github.com/apache/netbeans/pull/4533

   JEP 405 Record Patterns : Implement auto completion, adjust formatting and provide hints.


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: notifications-unsubscribe@netbeans.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@netbeans.apache.org
For additional commands, e-mail: notifications-help@netbeans.apache.org

For further information about the NetBeans mailing lists, visit:
https://cwiki.apache.org/confluence/display/NETBEANS/Mailing+lists


[GitHub] [netbeans] MegJayan commented on a diff in pull request #4533: Implementation of auto completion, formatting adjustment and providing hints for JEP 405 record patterns

Posted by GitBox <gi...@apache.org>.
MegJayan commented on code in PR #4533:
URL: https://github.com/apache/netbeans/pull/4533#discussion_r997794973


##########
java/java.source.base/src/org/netbeans/modules/java/source/pretty/VeryPretty.java:
##########
@@ -2091,8 +2092,30 @@ public void visitErroneous(JCErroneous tree) {
 
     @Override
     public void visitTree(JCTree tree) {
-	print("(UNKNOWN: " + tree + ")");
-	newline();
+        print("(UNKNOWN: " + tree + ")");
+        newline();
+    }
+    
+    @Override
+    public void visitRecordPattern(JCRecordPattern tree) {
+        print((JCExpression) tree.deconstructor);

Review Comment:
   addressed



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: notifications-unsubscribe@netbeans.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@netbeans.apache.org
For additional commands, e-mail: notifications-help@netbeans.apache.org

For further information about the NetBeans mailing lists, visit:
https://cwiki.apache.org/confluence/display/NETBEANS/Mailing+lists


[GitHub] [netbeans] MegJayan commented on a diff in pull request #4533: Implementation of auto completion, formatting adjustment and providing hints for JEP 405 record patterns

Posted by GitBox <gi...@apache.org>.
MegJayan commented on code in PR #4533:
URL: https://github.com/apache/netbeans/pull/4533#discussion_r998185690


##########
java/java.hints/src/org/netbeans/modules/java/hints/jdk/ConvertToNestedRecordPattern.java:
##########
@@ -0,0 +1,261 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.netbeans.modules.java.hints.jdk;
+
+import com.sun.source.tree.BindingPatternTree;
+import com.sun.source.tree.BlockTree;
+import com.sun.source.tree.DeconstructionPatternTree;
+import com.sun.source.tree.ExpressionTree;
+import com.sun.source.tree.IfTree;
+import com.sun.source.tree.InstanceOfTree;
+import com.sun.source.tree.ParenthesizedTree;
+import com.sun.source.tree.PatternTree;
+import com.sun.source.tree.StatementTree;
+import com.sun.source.tree.Tree;
+import com.sun.source.util.TreePath;
+import com.sun.source.tree.VariableTree;
+import com.sun.source.util.TreePathScanner;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.EnumSet;
+import java.util.Map;
+import java.util.Set;
+import java.util.stream.Collectors;
+import javax.lang.model.SourceVersion;
+import javax.lang.model.element.Modifier;
+import javax.lang.model.element.RecordComponentElement;
+import javax.lang.model.element.TypeElement;
+import org.netbeans.api.java.source.CompilationInfo;
+import org.netbeans.api.java.source.TreePathHandle;
+import org.netbeans.api.java.source.CodeStyleUtils;
+import org.netbeans.api.java.source.WorkingCopy;
+import org.netbeans.api.java.queries.CompilerOptionsQuery;
+import org.netbeans.modules.java.hints.errors.Utilities;
+import org.netbeans.spi.editor.hints.ErrorDescription;
+import org.netbeans.spi.editor.hints.Fix;
+import org.netbeans.spi.java.hints.ErrorDescriptionFactory;
+import org.netbeans.spi.java.hints.Hint;
+import org.netbeans.spi.java.hints.HintContext;
+import org.netbeans.spi.java.hints.JavaFix;
+import org.netbeans.spi.java.hints.MatcherUtilities;
+import org.netbeans.spi.java.hints.TriggerTreeKind;
+import org.openide.util.NbBundle;
+
+@NbBundle.Messages({
+    "DN_ConvertToNestedRecordPattern=Convert to nested record pattern",
+    "DESC_ConvertToNestedRecordPattern=Convert to nested record pattern",
+    "ERR_ConvertToNestedRecordPattern=Convert to nested record pattern",
+    "FIX_ConvertToNestedRecordPattern=Convert to nested record pattern"
+})
+@Hint(displayName = "#DN_ConvertToNestedRecordPattern", description = "#DESC_ConvertToNestedRecordPattern", category = "rules15",
+        minSourceVersion = "19")
+/**
+ *
+ * @author mjayan
+ */
+public class ConvertToNestedRecordPattern {
+
+    private static final int RECORD_PATTERN_PREVIEW_JDK_VERSION = 19;
+
+    @TriggerTreeKind(Tree.Kind.DECONSTRUCTION_PATTERN)
+    public static ErrorDescription convertToNestedRecordPattern(HintContext ctx) {
+        if (Utilities.isJDKVersionLower(RECORD_PATTERN_PREVIEW_JDK_VERSION) && !CompilerOptionsQuery.getOptions(ctx.getInfo().getFileObject()).getArguments().contains("--enable-preview")) {
+            return null;
+        }
+        TreePath t = ctx.getPath();
+        if (!t.getParentPath().getLeaf().getKind().equals(Tree.Kind.INSTANCE_OF)) {
+            return null;
+        }
+        Set<String> recordPatternVarSet = new HashSet<>();
+        Map<PatternTree, List<PatternTree>> recordComponentMap = new LinkedHashMap<>();
+        DeconstructionPatternTree recordPattern = (DeconstructionPatternTree) t.getLeaf();
+        recordComponentMap = findNested(recordPattern, recordComponentMap);
+
+        for (PatternTree p : recordComponentMap.keySet()) {
+            BindingPatternTree bTree = (BindingPatternTree) p;
+            recordPatternVarSet.add(bTree.getVariable().getName().toString());
+        }
+        while (t != null && t.getLeaf().getKind() != Tree.Kind.IF) {

Review Comment:
   handled by checking for immediately enclosing block



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: notifications-unsubscribe@netbeans.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@netbeans.apache.org
For additional commands, e-mail: notifications-help@netbeans.apache.org

For further information about the NetBeans mailing lists, visit:
https://cwiki.apache.org/confluence/display/NETBEANS/Mailing+lists


[GitHub] [netbeans] MegJayan commented on a diff in pull request #4533: Implementation of auto completion, formatting adjustment and providing hints for JEP 405 record patterns

Posted by GitBox <gi...@apache.org>.
MegJayan commented on code in PR #4533:
URL: https://github.com/apache/netbeans/pull/4533#discussion_r996652911


##########
java/java.source.base/src/org/netbeans/modules/java/source/pretty/VeryPretty.java:
##########
@@ -2091,8 +2092,30 @@ public void visitErroneous(JCErroneous tree) {
 
     @Override
     public void visitTree(JCTree tree) {
-	print("(UNKNOWN: " + tree + ")");
-	newline();
+        print("(UNKNOWN: " + tree + ")");
+        newline();
+    }
+    
+    @Override
+    public void visitRecordPattern(JCRecordPattern tree) {
+        print((JCExpression) tree.deconstructor);
+        print("(");
+        Iterator<JCPattern> it = tree.nested.iterator();
+        while (it.hasNext()) {
+            JCPattern pattern = it.next();
+            if (pattern instanceof JCBindingPattern) {

Review Comment:
   @lahodaj : doAccept(pattern, true) takes a pattern of type DocTree right? Is it proper to use this here as we are not dealing with patterns of type documentation syntax tree?



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: notifications-unsubscribe@netbeans.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@netbeans.apache.org
For additional commands, e-mail: notifications-help@netbeans.apache.org

For further information about the NetBeans mailing lists, visit:
https://cwiki.apache.org/confluence/display/NETBEANS/Mailing+lists


[GitHub] [netbeans] lahodaj commented on a diff in pull request #4533: Implementation of auto completion, formatting adjustment and providing hints for JEP 405 record patterns

Posted by GitBox <gi...@apache.org>.
lahodaj commented on code in PR #4533:
URL: https://github.com/apache/netbeans/pull/4533#discussion_r991869258


##########
java/java.source.base/src/org/netbeans/modules/java/source/pretty/VeryPretty.java:
##########
@@ -2091,8 +2092,30 @@ public void visitErroneous(JCErroneous tree) {
 
     @Override
     public void visitTree(JCTree tree) {
-	print("(UNKNOWN: " + tree + ")");
-	newline();
+        print("(UNKNOWN: " + tree + ")");
+        newline();
+    }
+    
+    @Override
+    public void visitRecordPattern(JCRecordPattern tree) {
+        print((JCExpression) tree.deconstructor);

Review Comment:
   Nit: `tree.deconstructor` should be of type `JCExpression`, the cast seems unnecessary?



##########
java/java.hints/src/org/netbeans/modules/java/hints/jdk/ConvertToNestedRecordPattern.java:
##########
@@ -0,0 +1,261 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.netbeans.modules.java.hints.jdk;
+
+import com.sun.source.tree.BindingPatternTree;
+import com.sun.source.tree.BlockTree;
+import com.sun.source.tree.DeconstructionPatternTree;
+import com.sun.source.tree.ExpressionTree;
+import com.sun.source.tree.IfTree;
+import com.sun.source.tree.InstanceOfTree;
+import com.sun.source.tree.ParenthesizedTree;
+import com.sun.source.tree.PatternTree;
+import com.sun.source.tree.StatementTree;
+import com.sun.source.tree.Tree;
+import com.sun.source.util.TreePath;
+import com.sun.source.tree.VariableTree;
+import com.sun.source.util.TreePathScanner;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.EnumSet;
+import java.util.Map;
+import java.util.Set;
+import java.util.stream.Collectors;
+import javax.lang.model.SourceVersion;
+import javax.lang.model.element.Modifier;
+import javax.lang.model.element.RecordComponentElement;
+import javax.lang.model.element.TypeElement;
+import org.netbeans.api.java.source.CompilationInfo;
+import org.netbeans.api.java.source.TreePathHandle;
+import org.netbeans.api.java.source.CodeStyleUtils;
+import org.netbeans.api.java.source.WorkingCopy;
+import org.netbeans.api.java.queries.CompilerOptionsQuery;
+import org.netbeans.modules.java.hints.errors.Utilities;
+import org.netbeans.spi.editor.hints.ErrorDescription;
+import org.netbeans.spi.editor.hints.Fix;
+import org.netbeans.spi.java.hints.ErrorDescriptionFactory;
+import org.netbeans.spi.java.hints.Hint;
+import org.netbeans.spi.java.hints.HintContext;
+import org.netbeans.spi.java.hints.JavaFix;
+import org.netbeans.spi.java.hints.MatcherUtilities;
+import org.netbeans.spi.java.hints.TriggerTreeKind;
+import org.openide.util.NbBundle;
+
+@NbBundle.Messages({
+    "DN_ConvertToNestedRecordPattern=Convert to nested record pattern",
+    "DESC_ConvertToNestedRecordPattern=Convert to nested record pattern",
+    "ERR_ConvertToNestedRecordPattern=Convert to nested record pattern",
+    "FIX_ConvertToNestedRecordPattern=Convert to nested record pattern"
+})
+@Hint(displayName = "#DN_ConvertToNestedRecordPattern", description = "#DESC_ConvertToNestedRecordPattern", category = "rules15",
+        minSourceVersion = "19")
+/**
+ *
+ * @author mjayan
+ */
+public class ConvertToNestedRecordPattern {
+
+    private static final int RECORD_PATTERN_PREVIEW_JDK_VERSION = 19;
+
+    @TriggerTreeKind(Tree.Kind.DECONSTRUCTION_PATTERN)
+    public static ErrorDescription convertToNestedRecordPattern(HintContext ctx) {
+        if (Utilities.isJDKVersionLower(RECORD_PATTERN_PREVIEW_JDK_VERSION) && !CompilerOptionsQuery.getOptions(ctx.getInfo().getFileObject()).getArguments().contains("--enable-preview")) {
+            return null;
+        }
+        TreePath t = ctx.getPath();
+        if (!t.getParentPath().getLeaf().getKind().equals(Tree.Kind.INSTANCE_OF)) {
+            return null;
+        }
+        Set<String> recordPatternVarSet = new HashSet<>();
+        Map<PatternTree, List<PatternTree>> recordComponentMap = new LinkedHashMap<>();
+        DeconstructionPatternTree recordPattern = (DeconstructionPatternTree) t.getLeaf();
+        recordComponentMap = findNested(recordPattern, recordComponentMap);
+
+        for (PatternTree p : recordComponentMap.keySet()) {
+            BindingPatternTree bTree = (BindingPatternTree) p;
+            recordPatternVarSet.add(bTree.getVariable().getName().toString());
+        }
+        while (t != null && t.getLeaf().getKind() != Tree.Kind.IF) {
+            t = t.getParentPath();
+        }
+        Set<TreePath> convertPath = new HashSet<>();
+        List<String> localVarList = new ArrayList<>();
+        Map<String, List<UserVariables>> userVars = new HashMap<>();
+        new TreePathScanner<Void, Void>() {

Review Comment:
   Maybe try to use `CancelableTreePathScanner` and try to cancel the process is the hint is canceled (esp. if we are going to search bigger parts of the source code).



##########
java/java.source.base/src/org/netbeans/modules/java/source/pretty/VeryPretty.java:
##########
@@ -2091,8 +2092,30 @@ public void visitErroneous(JCErroneous tree) {
 
     @Override
     public void visitTree(JCTree tree) {
-	print("(UNKNOWN: " + tree + ")");
-	newline();
+        print("(UNKNOWN: " + tree + ")");
+        newline();
+    }
+    
+    @Override
+    public void visitRecordPattern(JCRecordPattern tree) {
+        print((JCExpression) tree.deconstructor);
+        print("(");
+        Iterator<JCPattern> it = tree.nested.iterator();
+        while (it.hasNext()) {
+            JCPattern pattern = it.next();
+            if (pattern instanceof JCBindingPattern) {

Review Comment:
   I don't think we should test the type of the tree here, and call different methods based on the type of the pattern. Among other things, it would mean we would need to update this every time a new pattern type is added. How about using `doAccept(pattern, true)`?



##########
java/java.hints/src/org/netbeans/modules/java/hints/jdk/ConvertToNestedRecordPattern.java:
##########
@@ -0,0 +1,261 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.netbeans.modules.java.hints.jdk;
+
+import com.sun.source.tree.BindingPatternTree;
+import com.sun.source.tree.BlockTree;
+import com.sun.source.tree.DeconstructionPatternTree;
+import com.sun.source.tree.ExpressionTree;
+import com.sun.source.tree.IfTree;
+import com.sun.source.tree.InstanceOfTree;
+import com.sun.source.tree.ParenthesizedTree;
+import com.sun.source.tree.PatternTree;
+import com.sun.source.tree.StatementTree;
+import com.sun.source.tree.Tree;
+import com.sun.source.util.TreePath;
+import com.sun.source.tree.VariableTree;
+import com.sun.source.util.TreePathScanner;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.EnumSet;
+import java.util.Map;
+import java.util.Set;
+import java.util.stream.Collectors;
+import javax.lang.model.SourceVersion;
+import javax.lang.model.element.Modifier;
+import javax.lang.model.element.RecordComponentElement;
+import javax.lang.model.element.TypeElement;
+import org.netbeans.api.java.source.CompilationInfo;
+import org.netbeans.api.java.source.TreePathHandle;
+import org.netbeans.api.java.source.CodeStyleUtils;
+import org.netbeans.api.java.source.WorkingCopy;
+import org.netbeans.api.java.queries.CompilerOptionsQuery;
+import org.netbeans.modules.java.hints.errors.Utilities;
+import org.netbeans.spi.editor.hints.ErrorDescription;
+import org.netbeans.spi.editor.hints.Fix;
+import org.netbeans.spi.java.hints.ErrorDescriptionFactory;
+import org.netbeans.spi.java.hints.Hint;
+import org.netbeans.spi.java.hints.HintContext;
+import org.netbeans.spi.java.hints.JavaFix;
+import org.netbeans.spi.java.hints.MatcherUtilities;
+import org.netbeans.spi.java.hints.TriggerTreeKind;
+import org.openide.util.NbBundle;
+
+@NbBundle.Messages({
+    "DN_ConvertToNestedRecordPattern=Convert to nested record pattern",
+    "DESC_ConvertToNestedRecordPattern=Convert to nested record pattern",
+    "ERR_ConvertToNestedRecordPattern=Convert to nested record pattern",
+    "FIX_ConvertToNestedRecordPattern=Convert to nested record pattern"
+})
+@Hint(displayName = "#DN_ConvertToNestedRecordPattern", description = "#DESC_ConvertToNestedRecordPattern", category = "rules15",
+        minSourceVersion = "19")
+/**
+ *
+ * @author mjayan
+ */
+public class ConvertToNestedRecordPattern {
+
+    private static final int RECORD_PATTERN_PREVIEW_JDK_VERSION = 19;
+
+    @TriggerTreeKind(Tree.Kind.DECONSTRUCTION_PATTERN)
+    public static ErrorDescription convertToNestedRecordPattern(HintContext ctx) {
+        if (Utilities.isJDKVersionLower(RECORD_PATTERN_PREVIEW_JDK_VERSION) && !CompilerOptionsQuery.getOptions(ctx.getInfo().getFileObject()).getArguments().contains("--enable-preview")) {
+            return null;
+        }
+        TreePath t = ctx.getPath();
+        if (!t.getParentPath().getLeaf().getKind().equals(Tree.Kind.INSTANCE_OF)) {
+            return null;
+        }
+        Set<String> recordPatternVarSet = new HashSet<>();
+        Map<PatternTree, List<PatternTree>> recordComponentMap = new LinkedHashMap<>();
+        DeconstructionPatternTree recordPattern = (DeconstructionPatternTree) t.getLeaf();
+        recordComponentMap = findNested(recordPattern, recordComponentMap);
+
+        for (PatternTree p : recordComponentMap.keySet()) {
+            BindingPatternTree bTree = (BindingPatternTree) p;
+            recordPatternVarSet.add(bTree.getVariable().getName().toString());
+        }
+        while (t != null && t.getLeaf().getKind() != Tree.Kind.IF) {

Review Comment:
   Note this will find an `if` arbitrarily far from the original pattern. Even in the current code, it might be something like:
   ```
   if (true) {
       boolean b = o instanceof R1(R2 r2) && r2.v() != null;
   }
   ```
   
   As I read the code, the above would probably work (more or less by accident), but would not without the enclosing `if`. Also, the scope of a variable may extend beyond the current statement, like in:
   ```
   if (!(o instanceof R1(R2 r2))) { return ; }
   System.err.println(r2.v()); //OK to use r2 here
   }
   ```
   
   Maybe we want to find the innermost enclosing block (or innermost enclosing lambda or case, as lambdas and cases not necessarily have a block - OTOH, I suspect searching bigger chunk of the code shouldn't have functional effect, so it might be OK to simply scan the innermost block for simplicity)?



##########
java/java.hints/src/org/netbeans/modules/java/hints/jdk/ConvertToNestedRecordPattern.java:
##########
@@ -0,0 +1,261 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.netbeans.modules.java.hints.jdk;
+
+import com.sun.source.tree.BindingPatternTree;
+import com.sun.source.tree.BlockTree;
+import com.sun.source.tree.DeconstructionPatternTree;
+import com.sun.source.tree.ExpressionTree;
+import com.sun.source.tree.IfTree;
+import com.sun.source.tree.InstanceOfTree;
+import com.sun.source.tree.ParenthesizedTree;
+import com.sun.source.tree.PatternTree;
+import com.sun.source.tree.StatementTree;
+import com.sun.source.tree.Tree;
+import com.sun.source.util.TreePath;
+import com.sun.source.tree.VariableTree;
+import com.sun.source.util.TreePathScanner;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.EnumSet;
+import java.util.Map;
+import java.util.Set;
+import java.util.stream.Collectors;
+import javax.lang.model.SourceVersion;
+import javax.lang.model.element.Modifier;
+import javax.lang.model.element.RecordComponentElement;
+import javax.lang.model.element.TypeElement;
+import org.netbeans.api.java.source.CompilationInfo;
+import org.netbeans.api.java.source.TreePathHandle;
+import org.netbeans.api.java.source.CodeStyleUtils;
+import org.netbeans.api.java.source.WorkingCopy;
+import org.netbeans.api.java.queries.CompilerOptionsQuery;
+import org.netbeans.modules.java.hints.errors.Utilities;
+import org.netbeans.spi.editor.hints.ErrorDescription;
+import org.netbeans.spi.editor.hints.Fix;
+import org.netbeans.spi.java.hints.ErrorDescriptionFactory;
+import org.netbeans.spi.java.hints.Hint;
+import org.netbeans.spi.java.hints.HintContext;
+import org.netbeans.spi.java.hints.JavaFix;
+import org.netbeans.spi.java.hints.MatcherUtilities;
+import org.netbeans.spi.java.hints.TriggerTreeKind;
+import org.openide.util.NbBundle;
+
+@NbBundle.Messages({
+    "DN_ConvertToNestedRecordPattern=Convert to nested record pattern",
+    "DESC_ConvertToNestedRecordPattern=Convert to nested record pattern",
+    "ERR_ConvertToNestedRecordPattern=Convert to nested record pattern",
+    "FIX_ConvertToNestedRecordPattern=Convert to nested record pattern"
+})
+@Hint(displayName = "#DN_ConvertToNestedRecordPattern", description = "#DESC_ConvertToNestedRecordPattern", category = "rules15",
+        minSourceVersion = "19")
+/**
+ *
+ * @author mjayan
+ */
+public class ConvertToNestedRecordPattern {
+
+    private static final int RECORD_PATTERN_PREVIEW_JDK_VERSION = 19;
+
+    @TriggerTreeKind(Tree.Kind.DECONSTRUCTION_PATTERN)
+    public static ErrorDescription convertToNestedRecordPattern(HintContext ctx) {
+        if (Utilities.isJDKVersionLower(RECORD_PATTERN_PREVIEW_JDK_VERSION) && !CompilerOptionsQuery.getOptions(ctx.getInfo().getFileObject()).getArguments().contains("--enable-preview")) {
+            return null;
+        }
+        TreePath t = ctx.getPath();
+        if (!t.getParentPath().getLeaf().getKind().equals(Tree.Kind.INSTANCE_OF)) {
+            return null;
+        }
+        Set<String> recordPatternVarSet = new HashSet<>();
+        Map<PatternTree, List<PatternTree>> recordComponentMap = new LinkedHashMap<>();
+        DeconstructionPatternTree recordPattern = (DeconstructionPatternTree) t.getLeaf();
+        recordComponentMap = findNested(recordPattern, recordComponentMap);
+
+        for (PatternTree p : recordComponentMap.keySet()) {
+            BindingPatternTree bTree = (BindingPatternTree) p;
+            recordPatternVarSet.add(bTree.getVariable().getName().toString());
+        }
+        while (t != null && t.getLeaf().getKind() != Tree.Kind.IF) {
+            t = t.getParentPath();
+        }
+        Set<TreePath> convertPath = new HashSet<>();
+        List<String> localVarList = new ArrayList<>();
+        Map<String, List<UserVariables>> userVars = new HashMap<>();
+        new TreePathScanner<Void, Void>() {
+
+            @Override
+            public Void visitVariable(VariableTree node, Void p) {
+                localVarList.add(node.getName().toString());
+                Map<String, TreePath> outerVariables = new HashMap<>();
+                Map<String, String> innerVariables = new HashMap<>();
+                List<UserVariables> nList = new ArrayList<>();
+                boolean match = MatcherUtilities.matches(ctx, getCurrentPath(), "$type $var1 = $expr3.$meth1()", outerVariables, new HashMap<>(), innerVariables);
+
+                if (match && recordPatternVarSet.contains(outerVariables.get("$expr3").getLeaf().toString())) {
+                    String expr3 = outerVariables.get("$expr3").getLeaf().toString();
+                    nList.clear();
+                    if (userVars.get(expr3) != null) {
+                        nList = userVars.get(expr3);
+                    }
+                    nList.add(new UserVariables(innerVariables.get("$var1"), innerVariables.get("$meth1")));
+                    userVars.put(expr3, nList);
+                    convertPath.add(getCurrentPath());
+                }
+                return super.visitVariable(node, p);
+            }
+        }.scan(t, null);
+        if (!convertPath.isEmpty()) {
+            Fix fix = new FixImpl(ctx.getInfo(), ctx.getPath(), convertPath, localVarList, userVars).toEditorFix();
+            return ErrorDescriptionFactory.forName(ctx, ctx.getPath(), Bundle.ERR_ConvertToNestedRecordPattern(), fix);
+        }
+        return null;
+    }
+
+    private static Map<PatternTree, List<PatternTree>> findNested(PatternTree pTree, Map<PatternTree, List<PatternTree>> recordComponentMap) {
+        if (pTree instanceof BindingPatternTree) {
+            recordComponentMap.put(pTree, new ArrayList<>());
+            return recordComponentMap;
+        } else {
+            DeconstructionPatternTree bTree = (DeconstructionPatternTree) pTree;

Review Comment:
   Please note we also have parenthesized patterns.



##########
java/java.hints/src/org/netbeans/modules/java/hints/jdk/ConvertToNestedRecordPattern.java:
##########
@@ -0,0 +1,261 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.netbeans.modules.java.hints.jdk;
+
+import com.sun.source.tree.BindingPatternTree;
+import com.sun.source.tree.BlockTree;
+import com.sun.source.tree.DeconstructionPatternTree;
+import com.sun.source.tree.ExpressionTree;
+import com.sun.source.tree.IfTree;
+import com.sun.source.tree.InstanceOfTree;
+import com.sun.source.tree.ParenthesizedTree;
+import com.sun.source.tree.PatternTree;
+import com.sun.source.tree.StatementTree;
+import com.sun.source.tree.Tree;
+import com.sun.source.util.TreePath;
+import com.sun.source.tree.VariableTree;
+import com.sun.source.util.TreePathScanner;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.EnumSet;
+import java.util.Map;
+import java.util.Set;
+import java.util.stream.Collectors;
+import javax.lang.model.SourceVersion;
+import javax.lang.model.element.Modifier;
+import javax.lang.model.element.RecordComponentElement;
+import javax.lang.model.element.TypeElement;
+import org.netbeans.api.java.source.CompilationInfo;
+import org.netbeans.api.java.source.TreePathHandle;
+import org.netbeans.api.java.source.CodeStyleUtils;
+import org.netbeans.api.java.source.WorkingCopy;
+import org.netbeans.api.java.queries.CompilerOptionsQuery;
+import org.netbeans.modules.java.hints.errors.Utilities;
+import org.netbeans.spi.editor.hints.ErrorDescription;
+import org.netbeans.spi.editor.hints.Fix;
+import org.netbeans.spi.java.hints.ErrorDescriptionFactory;
+import org.netbeans.spi.java.hints.Hint;
+import org.netbeans.spi.java.hints.HintContext;
+import org.netbeans.spi.java.hints.JavaFix;
+import org.netbeans.spi.java.hints.MatcherUtilities;
+import org.netbeans.spi.java.hints.TriggerTreeKind;
+import org.openide.util.NbBundle;
+
+@NbBundle.Messages({
+    "DN_ConvertToNestedRecordPattern=Convert to nested record pattern",
+    "DESC_ConvertToNestedRecordPattern=Convert to nested record pattern",
+    "ERR_ConvertToNestedRecordPattern=Convert to nested record pattern",
+    "FIX_ConvertToNestedRecordPattern=Convert to nested record pattern"
+})
+@Hint(displayName = "#DN_ConvertToNestedRecordPattern", description = "#DESC_ConvertToNestedRecordPattern", category = "rules15",
+        minSourceVersion = "19")
+/**
+ *
+ * @author mjayan
+ */
+public class ConvertToNestedRecordPattern {
+
+    private static final int RECORD_PATTERN_PREVIEW_JDK_VERSION = 19;
+
+    @TriggerTreeKind(Tree.Kind.DECONSTRUCTION_PATTERN)
+    public static ErrorDescription convertToNestedRecordPattern(HintContext ctx) {
+        if (Utilities.isJDKVersionLower(RECORD_PATTERN_PREVIEW_JDK_VERSION) && !CompilerOptionsQuery.getOptions(ctx.getInfo().getFileObject()).getArguments().contains("--enable-preview")) {
+            return null;
+        }
+        TreePath t = ctx.getPath();
+        if (!t.getParentPath().getLeaf().getKind().equals(Tree.Kind.INSTANCE_OF)) {
+            return null;
+        }
+        Set<String> recordPatternVarSet = new HashSet<>();
+        Map<PatternTree, List<PatternTree>> recordComponentMap = new LinkedHashMap<>();
+        DeconstructionPatternTree recordPattern = (DeconstructionPatternTree) t.getLeaf();
+        recordComponentMap = findNested(recordPattern, recordComponentMap);
+
+        for (PatternTree p : recordComponentMap.keySet()) {
+            BindingPatternTree bTree = (BindingPatternTree) p;
+            recordPatternVarSet.add(bTree.getVariable().getName().toString());
+        }
+        while (t != null && t.getLeaf().getKind() != Tree.Kind.IF) {
+            t = t.getParentPath();
+        }
+        Set<TreePath> convertPath = new HashSet<>();
+        List<String> localVarList = new ArrayList<>();
+        Map<String, List<UserVariables>> userVars = new HashMap<>();
+        new TreePathScanner<Void, Void>() {
+
+            @Override
+            public Void visitVariable(VariableTree node, Void p) {
+                localVarList.add(node.getName().toString());
+                Map<String, TreePath> outerVariables = new HashMap<>();
+                Map<String, String> innerVariables = new HashMap<>();
+                List<UserVariables> nList = new ArrayList<>();
+                boolean match = MatcherUtilities.matches(ctx, getCurrentPath(), "$type $var1 = $expr3.$meth1()", outerVariables, new HashMap<>(), innerVariables);
+
+                if (match && recordPatternVarSet.contains(outerVariables.get("$expr3").getLeaf().toString())) {
+                    String expr3 = outerVariables.get("$expr3").getLeaf().toString();
+                    nList.clear();
+                    if (userVars.get(expr3) != null) {
+                        nList = userVars.get(expr3);
+                    }
+                    nList.add(new UserVariables(innerVariables.get("$var1"), innerVariables.get("$meth1")));
+                    userVars.put(expr3, nList);
+                    convertPath.add(getCurrentPath());
+                }
+                return super.visitVariable(node, p);
+            }
+        }.scan(t, null);
+        if (!convertPath.isEmpty()) {
+            Fix fix = new FixImpl(ctx.getInfo(), ctx.getPath(), convertPath, localVarList, userVars).toEditorFix();
+            return ErrorDescriptionFactory.forName(ctx, ctx.getPath(), Bundle.ERR_ConvertToNestedRecordPattern(), fix);
+        }
+        return null;
+    }
+
+    private static Map<PatternTree, List<PatternTree>> findNested(PatternTree pTree, Map<PatternTree, List<PatternTree>> recordComponentMap) {
+        if (pTree instanceof BindingPatternTree) {
+            recordComponentMap.put(pTree, new ArrayList<>());
+            return recordComponentMap;
+        } else {
+            DeconstructionPatternTree bTree = (DeconstructionPatternTree) pTree;
+            for (PatternTree p : bTree.getNestedPatterns()) {
+                findNested(p, recordComponentMap);
+            }
+        }
+        return recordComponentMap;
+    }
+
+    private static class UserVariables {
+
+        String methodName;
+        String variable;
+
+        UserVariables(String variable, String methodName) {
+            this.variable = variable;
+            this.methodName = methodName;
+        }
+
+        public String getMethodName() {
+            return methodName;
+        }
+
+        public String getVariable() {
+            return variable;
+        }
+    }
+
+    private static final class FixImpl extends JavaFix {
+
+        private final Map<String, List<UserVariables>> userVars;
+        private final Set<TreePathHandle> replaceOccurrences;
+        List<String> localVarList;
+
+        public FixImpl(CompilationInfo info, TreePath main, Set<TreePath> replaceOccurrences, List<String> localVarList, Map<String, List<UserVariables>> userVars) {
+            super(info, main);
+            this.replaceOccurrences = replaceOccurrences.stream().map(tp -> TreePathHandle.create(tp, info)).collect(Collectors.toSet());
+            this.userVars = userVars;
+            this.localVarList = localVarList;
+        }
+
+        @Override
+        protected String getText() {
+            return Bundle.ERR_ConvertToNestedRecordPattern();
+        }
+
+        @Override
+        protected void performRewrite(JavaFix.TransformationContext ctx) {
+            WorkingCopy wc = ctx.getWorkingCopy();
+            TreePath t = ctx.getPath();
+            TypeElement type = null;
+            Map<PatternTree, List<PatternTree>> recordComponentMap = new LinkedHashMap<>();
+            DeconstructionPatternTree recordPattern = (DeconstructionPatternTree) t.getLeaf();
+            recordComponentMap = findNested(recordPattern, recordComponentMap);
+            
+            Set<String> localVars = new HashSet<>(localVarList);
+            for (PatternTree p : recordComponentMap.keySet()) {
+                List<PatternTree> bindTree = new ArrayList<>();
+                BindingPatternTree bTree = (BindingPatternTree) p;
+                VariableTree v = bTree.getVariable();
+                type = (TypeElement) wc.getTrees().getElement(TreePath.getPath(t, v.getType()));
+                if (type == null || type.getRecordComponents().size() == 0) {
+                    continue;
+                }
+                outer:
+                for (RecordComponentElement recordComponent : type.getRecordComponents()) {
+                    String name = recordComponent.getSimpleName().toString();
+                    String returnType = recordComponent.getAccessor().getReturnType().toString();
+                    returnType = returnType.substring(returnType.lastIndexOf(".") + 1);

Review Comment:
   There shouldn't be a need to do String manipulation over the (String representation of the) type. Simply keep the `TypeMirror`, and then use `TreeMaker.Type(TypeMirror)`. That method should take care about printing the correct type, with correct imports, etc.



##########
java/java.hints/src/org/netbeans/modules/java/hints/jdk/ConvertToNestedRecordPattern.java:
##########
@@ -0,0 +1,261 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.netbeans.modules.java.hints.jdk;
+
+import com.sun.source.tree.BindingPatternTree;
+import com.sun.source.tree.BlockTree;
+import com.sun.source.tree.DeconstructionPatternTree;
+import com.sun.source.tree.ExpressionTree;
+import com.sun.source.tree.IfTree;
+import com.sun.source.tree.InstanceOfTree;
+import com.sun.source.tree.ParenthesizedTree;
+import com.sun.source.tree.PatternTree;
+import com.sun.source.tree.StatementTree;
+import com.sun.source.tree.Tree;
+import com.sun.source.util.TreePath;
+import com.sun.source.tree.VariableTree;
+import com.sun.source.util.TreePathScanner;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.EnumSet;
+import java.util.Map;
+import java.util.Set;
+import java.util.stream.Collectors;
+import javax.lang.model.SourceVersion;
+import javax.lang.model.element.Modifier;
+import javax.lang.model.element.RecordComponentElement;
+import javax.lang.model.element.TypeElement;
+import org.netbeans.api.java.source.CompilationInfo;
+import org.netbeans.api.java.source.TreePathHandle;
+import org.netbeans.api.java.source.CodeStyleUtils;
+import org.netbeans.api.java.source.WorkingCopy;
+import org.netbeans.api.java.queries.CompilerOptionsQuery;
+import org.netbeans.modules.java.hints.errors.Utilities;
+import org.netbeans.spi.editor.hints.ErrorDescription;
+import org.netbeans.spi.editor.hints.Fix;
+import org.netbeans.spi.java.hints.ErrorDescriptionFactory;
+import org.netbeans.spi.java.hints.Hint;
+import org.netbeans.spi.java.hints.HintContext;
+import org.netbeans.spi.java.hints.JavaFix;
+import org.netbeans.spi.java.hints.MatcherUtilities;
+import org.netbeans.spi.java.hints.TriggerTreeKind;
+import org.openide.util.NbBundle;
+
+@NbBundle.Messages({
+    "DN_ConvertToNestedRecordPattern=Convert to nested record pattern",
+    "DESC_ConvertToNestedRecordPattern=Convert to nested record pattern",
+    "ERR_ConvertToNestedRecordPattern=Convert to nested record pattern",
+    "FIX_ConvertToNestedRecordPattern=Convert to nested record pattern"
+})
+@Hint(displayName = "#DN_ConvertToNestedRecordPattern", description = "#DESC_ConvertToNestedRecordPattern", category = "rules15",
+        minSourceVersion = "19")
+/**
+ *
+ * @author mjayan
+ */
+public class ConvertToNestedRecordPattern {
+
+    private static final int RECORD_PATTERN_PREVIEW_JDK_VERSION = 19;
+
+    @TriggerTreeKind(Tree.Kind.DECONSTRUCTION_PATTERN)
+    public static ErrorDescription convertToNestedRecordPattern(HintContext ctx) {
+        if (Utilities.isJDKVersionLower(RECORD_PATTERN_PREVIEW_JDK_VERSION) && !CompilerOptionsQuery.getOptions(ctx.getInfo().getFileObject()).getArguments().contains("--enable-preview")) {
+            return null;
+        }
+        TreePath t = ctx.getPath();
+        if (!t.getParentPath().getLeaf().getKind().equals(Tree.Kind.INSTANCE_OF)) {
+            return null;
+        }
+        Set<String> recordPatternVarSet = new HashSet<>();
+        Map<PatternTree, List<PatternTree>> recordComponentMap = new LinkedHashMap<>();
+        DeconstructionPatternTree recordPattern = (DeconstructionPatternTree) t.getLeaf();
+        recordComponentMap = findNested(recordPattern, recordComponentMap);
+
+        for (PatternTree p : recordComponentMap.keySet()) {
+            BindingPatternTree bTree = (BindingPatternTree) p;
+            recordPatternVarSet.add(bTree.getVariable().getName().toString());
+        }
+        while (t != null && t.getLeaf().getKind() != Tree.Kind.IF) {
+            t = t.getParentPath();
+        }
+        Set<TreePath> convertPath = new HashSet<>();
+        List<String> localVarList = new ArrayList<>();
+        Map<String, List<UserVariables>> userVars = new HashMap<>();
+        new TreePathScanner<Void, Void>() {
+
+            @Override
+            public Void visitVariable(VariableTree node, Void p) {
+                localVarList.add(node.getName().toString());
+                Map<String, TreePath> outerVariables = new HashMap<>();
+                Map<String, String> innerVariables = new HashMap<>();
+                List<UserVariables> nList = new ArrayList<>();
+                boolean match = MatcherUtilities.matches(ctx, getCurrentPath(), "$type $var1 = $expr3.$meth1()", outerVariables, new HashMap<>(), innerVariables);
+
+                if (match && recordPatternVarSet.contains(outerVariables.get("$expr3").getLeaf().toString())) {
+                    String expr3 = outerVariables.get("$expr3").getLeaf().toString();
+                    nList.clear();
+                    if (userVars.get(expr3) != null) {
+                        nList = userVars.get(expr3);
+                    }
+                    nList.add(new UserVariables(innerVariables.get("$var1"), innerVariables.get("$meth1")));
+                    userVars.put(expr3, nList);
+                    convertPath.add(getCurrentPath());
+                }
+                return super.visitVariable(node, p);
+            }
+        }.scan(t, null);
+        if (!convertPath.isEmpty()) {
+            Fix fix = new FixImpl(ctx.getInfo(), ctx.getPath(), convertPath, localVarList, userVars).toEditorFix();
+            return ErrorDescriptionFactory.forName(ctx, ctx.getPath(), Bundle.ERR_ConvertToNestedRecordPattern(), fix);
+        }
+        return null;
+    }
+
+    private static Map<PatternTree, List<PatternTree>> findNested(PatternTree pTree, Map<PatternTree, List<PatternTree>> recordComponentMap) {
+        if (pTree instanceof BindingPatternTree) {

Review Comment:
   Better use `pTree.getKind()`, and switch over that kind, having a `default` with an exception. `instanceof` is not necessarily a safe idiom when working with `com.sun.source.tree`.



##########
java/java.hints/src/org/netbeans/modules/java/hints/jdk/ConvertToNestedRecordPattern.java:
##########
@@ -0,0 +1,261 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.netbeans.modules.java.hints.jdk;
+
+import com.sun.source.tree.BindingPatternTree;
+import com.sun.source.tree.BlockTree;
+import com.sun.source.tree.DeconstructionPatternTree;
+import com.sun.source.tree.ExpressionTree;
+import com.sun.source.tree.IfTree;
+import com.sun.source.tree.InstanceOfTree;
+import com.sun.source.tree.ParenthesizedTree;
+import com.sun.source.tree.PatternTree;
+import com.sun.source.tree.StatementTree;
+import com.sun.source.tree.Tree;
+import com.sun.source.util.TreePath;
+import com.sun.source.tree.VariableTree;
+import com.sun.source.util.TreePathScanner;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.EnumSet;
+import java.util.Map;
+import java.util.Set;
+import java.util.stream.Collectors;
+import javax.lang.model.SourceVersion;
+import javax.lang.model.element.Modifier;
+import javax.lang.model.element.RecordComponentElement;
+import javax.lang.model.element.TypeElement;
+import org.netbeans.api.java.source.CompilationInfo;
+import org.netbeans.api.java.source.TreePathHandle;
+import org.netbeans.api.java.source.CodeStyleUtils;
+import org.netbeans.api.java.source.WorkingCopy;
+import org.netbeans.api.java.queries.CompilerOptionsQuery;
+import org.netbeans.modules.java.hints.errors.Utilities;
+import org.netbeans.spi.editor.hints.ErrorDescription;
+import org.netbeans.spi.editor.hints.Fix;
+import org.netbeans.spi.java.hints.ErrorDescriptionFactory;
+import org.netbeans.spi.java.hints.Hint;
+import org.netbeans.spi.java.hints.HintContext;
+import org.netbeans.spi.java.hints.JavaFix;
+import org.netbeans.spi.java.hints.MatcherUtilities;
+import org.netbeans.spi.java.hints.TriggerTreeKind;
+import org.openide.util.NbBundle;
+
+@NbBundle.Messages({
+    "DN_ConvertToNestedRecordPattern=Convert to nested record pattern",
+    "DESC_ConvertToNestedRecordPattern=Convert to nested record pattern",
+    "ERR_ConvertToNestedRecordPattern=Convert to nested record pattern",
+    "FIX_ConvertToNestedRecordPattern=Convert to nested record pattern"
+})
+@Hint(displayName = "#DN_ConvertToNestedRecordPattern", description = "#DESC_ConvertToNestedRecordPattern", category = "rules15",
+        minSourceVersion = "19")
+/**
+ *
+ * @author mjayan
+ */
+public class ConvertToNestedRecordPattern {
+
+    private static final int RECORD_PATTERN_PREVIEW_JDK_VERSION = 19;
+
+    @TriggerTreeKind(Tree.Kind.DECONSTRUCTION_PATTERN)
+    public static ErrorDescription convertToNestedRecordPattern(HintContext ctx) {
+        if (Utilities.isJDKVersionLower(RECORD_PATTERN_PREVIEW_JDK_VERSION) && !CompilerOptionsQuery.getOptions(ctx.getInfo().getFileObject()).getArguments().contains("--enable-preview")) {
+            return null;
+        }
+        TreePath t = ctx.getPath();
+        if (!t.getParentPath().getLeaf().getKind().equals(Tree.Kind.INSTANCE_OF)) {
+            return null;
+        }
+        Set<String> recordPatternVarSet = new HashSet<>();
+        Map<PatternTree, List<PatternTree>> recordComponentMap = new LinkedHashMap<>();
+        DeconstructionPatternTree recordPattern = (DeconstructionPatternTree) t.getLeaf();
+        recordComponentMap = findNested(recordPattern, recordComponentMap);
+
+        for (PatternTree p : recordComponentMap.keySet()) {
+            BindingPatternTree bTree = (BindingPatternTree) p;
+            recordPatternVarSet.add(bTree.getVariable().getName().toString());
+        }
+        while (t != null && t.getLeaf().getKind() != Tree.Kind.IF) {
+            t = t.getParentPath();
+        }
+        Set<TreePath> convertPath = new HashSet<>();
+        List<String> localVarList = new ArrayList<>();
+        Map<String, List<UserVariables>> userVars = new HashMap<>();
+        new TreePathScanner<Void, Void>() {
+
+            @Override
+            public Void visitVariable(VariableTree node, Void p) {
+                localVarList.add(node.getName().toString());
+                Map<String, TreePath> outerVariables = new HashMap<>();
+                Map<String, String> innerVariables = new HashMap<>();
+                List<UserVariables> nList = new ArrayList<>();
+                boolean match = MatcherUtilities.matches(ctx, getCurrentPath(), "$type $var1 = $expr3.$meth1()", outerVariables, new HashMap<>(), innerVariables);
+
+                if (match && recordPatternVarSet.contains(outerVariables.get("$expr3").getLeaf().toString())) {
+                    String expr3 = outerVariables.get("$expr3").getLeaf().toString();
+                    nList.clear();
+                    if (userVars.get(expr3) != null) {
+                        nList = userVars.get(expr3);
+                    }
+                    nList.add(new UserVariables(innerVariables.get("$var1"), innerVariables.get("$meth1")));
+                    userVars.put(expr3, nList);
+                    convertPath.add(getCurrentPath());
+                }
+                return super.visitVariable(node, p);
+            }
+        }.scan(t, null);
+        if (!convertPath.isEmpty()) {
+            Fix fix = new FixImpl(ctx.getInfo(), ctx.getPath(), convertPath, localVarList, userVars).toEditorFix();
+            return ErrorDescriptionFactory.forName(ctx, ctx.getPath(), Bundle.ERR_ConvertToNestedRecordPattern(), fix);
+        }
+        return null;
+    }
+
+    private static Map<PatternTree, List<PatternTree>> findNested(PatternTree pTree, Map<PatternTree, List<PatternTree>> recordComponentMap) {
+        if (pTree instanceof BindingPatternTree) {
+            recordComponentMap.put(pTree, new ArrayList<>());
+            return recordComponentMap;
+        } else {
+            DeconstructionPatternTree bTree = (DeconstructionPatternTree) pTree;
+            for (PatternTree p : bTree.getNestedPatterns()) {
+                findNested(p, recordComponentMap);
+            }
+        }
+        return recordComponentMap;
+    }
+
+    private static class UserVariables {
+
+        String methodName;
+        String variable;
+
+        UserVariables(String variable, String methodName) {
+            this.variable = variable;
+            this.methodName = methodName;
+        }
+
+        public String getMethodName() {
+            return methodName;
+        }
+
+        public String getVariable() {
+            return variable;
+        }
+    }
+
+    private static final class FixImpl extends JavaFix {
+
+        private final Map<String, List<UserVariables>> userVars;
+        private final Set<TreePathHandle> replaceOccurrences;
+        List<String> localVarList;
+
+        public FixImpl(CompilationInfo info, TreePath main, Set<TreePath> replaceOccurrences, List<String> localVarList, Map<String, List<UserVariables>> userVars) {
+            super(info, main);
+            this.replaceOccurrences = replaceOccurrences.stream().map(tp -> TreePathHandle.create(tp, info)).collect(Collectors.toSet());
+            this.userVars = userVars;
+            this.localVarList = localVarList;
+        }
+
+        @Override
+        protected String getText() {
+            return Bundle.ERR_ConvertToNestedRecordPattern();
+        }
+
+        @Override
+        protected void performRewrite(JavaFix.TransformationContext ctx) {
+            WorkingCopy wc = ctx.getWorkingCopy();
+            TreePath t = ctx.getPath();
+            TypeElement type = null;
+            Map<PatternTree, List<PatternTree>> recordComponentMap = new LinkedHashMap<>();
+            DeconstructionPatternTree recordPattern = (DeconstructionPatternTree) t.getLeaf();
+            recordComponentMap = findNested(recordPattern, recordComponentMap);
+            
+            Set<String> localVars = new HashSet<>(localVarList);
+            for (PatternTree p : recordComponentMap.keySet()) {
+                List<PatternTree> bindTree = new ArrayList<>();
+                BindingPatternTree bTree = (BindingPatternTree) p;
+                VariableTree v = bTree.getVariable();
+                type = (TypeElement) wc.getTrees().getElement(TreePath.getPath(t, v.getType()));
+                if (type == null || type.getRecordComponents().size() == 0) {
+                    continue;
+                }
+                outer:
+                for (RecordComponentElement recordComponent : type.getRecordComponents()) {
+                    String name = recordComponent.getSimpleName().toString();
+                    String returnType = recordComponent.getAccessor().getReturnType().toString();
+                    returnType = returnType.substring(returnType.lastIndexOf(".") + 1);
+                    if (userVars.get(v.getName().toString()) != null) {
+                        for (UserVariables var : userVars.get(v.getName().toString())) {
+                            if (var.getMethodName().equals(name)) {
+                                bindTree.add((BindingPatternTree) wc.getTreeMaker().BindingPattern(wc.getTreeMaker().Variable(wc.getTreeMaker().
+                                        Modifiers(EnumSet.noneOf(Modifier.class)), var.getVariable(), wc.getTreeMaker().Identifier(returnType), null)));
+                                continue outer;
+                            }
+                        }
+                    }
+                    String baseName = name;
+                    int cnt = 1;
+                    while (SourceVersion.isKeyword(name) || localVars.contains(name)) {
+                        name = CodeStyleUtils.addPrefixSuffix(baseName + cnt++, "", "");
+                    }
+                    localVars.add(name);
+                    bindTree.add((BindingPatternTree) wc.getTreeMaker().BindingPattern(wc.getTreeMaker().Variable(wc.getTreeMaker().
+                            Modifiers(EnumSet.noneOf(Modifier.class)), name, wc.getTreeMaker().Identifier(returnType), null)));
+                }
+                recordComponentMap.put(p, bindTree);
+            }
+
+            DeconstructionPatternTree d = (DeconstructionPatternTree) createNestedPattern((PatternTree) t.getLeaf(), wc, recordComponentMap);
+            while (t != null && t.getLeaf().getKind() != Tree.Kind.IF) {
+                t = t.getParentPath();
+            }
+            IfTree it = (IfTree) t.getLeaf();
+            InstanceOfTree iot = (InstanceOfTree) ((ParenthesizedTree) it.getCondition()).getExpression();
+            StatementTree bt = it.getThenStatement();
+            InstanceOfTree cond = wc.getTreeMaker().InstanceOf(iot.getExpression(), d);
+            List<Tree> removeList = replaceOccurrences.stream().map(tph -> tph.resolve(wc).getLeaf()).collect(Collectors.toList());
+            for(Tree tree : removeList) {
+                bt = wc.getTreeMaker().removeBlockStatement((BlockTree) bt, (StatementTree) tree);
+            }
+            wc.rewrite(it, wc.getTreeMaker().If(wc.getTreeMaker().Parenthesized(cond), bt, it.getElseStatement()));
+        }
+    }
+
+    private static PatternTree createNestedPattern(PatternTree pTree, WorkingCopy wc, Map<PatternTree, List<PatternTree>> map) {
+        if (pTree instanceof BindingPatternTree) {

Review Comment:
   Please see the comment about using `instanceof` on the trees.



##########
java/java.hints/test/unit/src/org/netbeans/modules/java/hints/jdk/ConvertToNestedRecordPatternTest.java:
##########
@@ -0,0 +1,159 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.netbeans.modules.java.hints.jdk;
+
+import org.netbeans.junit.NbTestCase;
+import org.netbeans.modules.java.hints.test.api.HintTest;
+import javax.lang.model.SourceVersion;
+
+/**
+ *
+ * @author mjayan
+ */
+public class ConvertToNestedRecordPatternTest extends NbTestCase {
+
+    public ConvertToNestedRecordPatternTest(String name) {
+        super(name);
+    }
+
+    public void testSimple() throws Exception {
+        if (!isRecordClassPresent()) {
+            return;
+        }
+        HintTest.create()
+                .input("package test;\n"
+                        + "record Rect(ColoredPoint upperLeft,ColoredPoint lr) {}\n"
+                        + "record ColoredPoint(Point p, Color c) {}\n"
+                        + "record Point(int x, int y){}\n"
+                        + "enum Color {RED,GREEN,BLUE}\n"
+                        + "public class Test {\n"
+                        + "    private void test(Object o) {\n"
+                        + "        if (o instanceof Rect(ColoredPoint ul, ColoredPoint lr)) {\n"

Review Comment:
   One thing to note here is that for JDK 20, the named record patterns will likely be dropped, and only "unnamed" will remain. Might be reasonable to reflect that here even now.



##########
java/java.hints/src/org/netbeans/modules/java/hints/jdk/ConvertToRecordPattern.java:
##########
@@ -0,0 +1,190 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.netbeans.modules.java.hints.jdk;
+
+import com.sun.source.tree.BindingPatternTree;
+import com.sun.source.tree.BlockTree;
+import com.sun.source.tree.ExpressionTree;
+import com.sun.source.tree.IfTree;
+import com.sun.source.tree.InstanceOfTree;
+import com.sun.source.tree.ParenthesizedTree;
+import com.sun.source.tree.PatternTree;
+import com.sun.source.tree.StatementTree;
+import com.sun.source.tree.Tree;
+import com.sun.source.util.TreePath;
+import com.sun.source.util.TreePathScanner;
+import com.sun.source.tree.VariableTree;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.EnumSet;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.stream.Collectors;
+import javax.lang.model.SourceVersion;
+import javax.lang.model.element.ElementKind;
+import javax.lang.model.element.Modifier;
+import javax.lang.model.element.RecordComponentElement;
+import javax.lang.model.element.TypeElement;
+import org.netbeans.api.java.source.CodeStyleUtils;
+import org.netbeans.api.java.source.CompilationInfo;
+import org.netbeans.api.java.source.TreePathHandle;
+import org.netbeans.api.java.source.ElementHandle;
+import org.netbeans.api.java.source.WorkingCopy;
+import org.netbeans.api.java.queries.CompilerOptionsQuery;
+import org.netbeans.modules.java.hints.errors.Utilities;
+import org.netbeans.spi.editor.hints.ErrorDescription;
+import org.netbeans.spi.editor.hints.Fix;
+import org.netbeans.spi.java.hints.ErrorDescriptionFactory;
+import org.netbeans.spi.java.hints.Hint;
+import org.netbeans.spi.java.hints.HintContext;
+import org.netbeans.spi.java.hints.JavaFix;
+import org.netbeans.spi.java.hints.MatcherUtilities;
+import org.netbeans.spi.java.hints.TriggerPattern;
+import org.netbeans.spi.java.hints.TriggerPatterns;
+import org.openide.util.NbBundle;
+
+/**
+ *
+ * @author mjayan
+ */
+@NbBundle.Messages({
+    "DN_ConvertToRecordPattern=Convert to instanceof <record pattern>",
+    "DESC_ConvertToRecordPattern=Convert to instanceof <record pattern>",
+    "ERR_ConvertToRecordPattern=instanceof <record pattern> can be used here",
+    "FIX_ConvertToRecordPattern=Use instanceof <record pattern>"
+})
+@Hint(displayName = "#DN_ConvertToRecordPattern", description = "#DESC_ConvertToRecordPattern", category = "rules15",
+        minSourceVersion = "19")
+public class ConvertToRecordPattern {
+ 
+    private static final int RECORD_PATTERN_PREVIEW_JDK_VERSION = 19;
+
+    @TriggerPatterns({
+        @TriggerPattern(value = "if ($expr instanceof $typeI0 $var0 ) { $statements$;} else $else$;")
+    })
+    public static ErrorDescription trivial(HintContext ctx) {
+        if (Utilities.isJDKVersionLower(RECORD_PATTERN_PREVIEW_JDK_VERSION) && !CompilerOptionsQuery.getOptions(ctx.getInfo().getFileObject()).getArguments().contains("--enable-preview")) {
+            return null;
+        }
+        ElementKind kind = ctx.getInfo().getTrees().getElement(ctx.getVariables().get("$typeI0")).getKind();
+        if (kind.equals(ElementKind.RECORD)) {
+            Set<TreePath> convertPath = new HashSet<>();
+            Set<String> localVarList = new HashSet<>();
+            localVarList.add(ctx.getInfo().getTrees().getElement(ctx.getVariables().get("$expr")).getSimpleName().toString());
+            Map<String, String> varNames = new HashMap<>();
+            new TreePathScanner<Void, Void>() {

Review Comment:
   Nit: possibly `CancelableTreePathScanner` (and use `HintContext.isCanceled()` to cancel).



##########
java/java.hints/src/org/netbeans/modules/java/hints/jdk/ConvertToNestedRecordPattern.java:
##########
@@ -0,0 +1,261 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.netbeans.modules.java.hints.jdk;
+
+import com.sun.source.tree.BindingPatternTree;
+import com.sun.source.tree.BlockTree;
+import com.sun.source.tree.DeconstructionPatternTree;
+import com.sun.source.tree.ExpressionTree;
+import com.sun.source.tree.IfTree;
+import com.sun.source.tree.InstanceOfTree;
+import com.sun.source.tree.ParenthesizedTree;
+import com.sun.source.tree.PatternTree;
+import com.sun.source.tree.StatementTree;
+import com.sun.source.tree.Tree;
+import com.sun.source.util.TreePath;
+import com.sun.source.tree.VariableTree;
+import com.sun.source.util.TreePathScanner;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.EnumSet;
+import java.util.Map;
+import java.util.Set;
+import java.util.stream.Collectors;
+import javax.lang.model.SourceVersion;
+import javax.lang.model.element.Modifier;
+import javax.lang.model.element.RecordComponentElement;
+import javax.lang.model.element.TypeElement;
+import org.netbeans.api.java.source.CompilationInfo;
+import org.netbeans.api.java.source.TreePathHandle;
+import org.netbeans.api.java.source.CodeStyleUtils;
+import org.netbeans.api.java.source.WorkingCopy;
+import org.netbeans.api.java.queries.CompilerOptionsQuery;
+import org.netbeans.modules.java.hints.errors.Utilities;
+import org.netbeans.spi.editor.hints.ErrorDescription;
+import org.netbeans.spi.editor.hints.Fix;
+import org.netbeans.spi.java.hints.ErrorDescriptionFactory;
+import org.netbeans.spi.java.hints.Hint;
+import org.netbeans.spi.java.hints.HintContext;
+import org.netbeans.spi.java.hints.JavaFix;
+import org.netbeans.spi.java.hints.MatcherUtilities;
+import org.netbeans.spi.java.hints.TriggerTreeKind;
+import org.openide.util.NbBundle;
+
+@NbBundle.Messages({
+    "DN_ConvertToNestedRecordPattern=Convert to nested record pattern",
+    "DESC_ConvertToNestedRecordPattern=Convert to nested record pattern",
+    "ERR_ConvertToNestedRecordPattern=Convert to nested record pattern",
+    "FIX_ConvertToNestedRecordPattern=Convert to nested record pattern"
+})
+@Hint(displayName = "#DN_ConvertToNestedRecordPattern", description = "#DESC_ConvertToNestedRecordPattern", category = "rules15",
+        minSourceVersion = "19")
+/**
+ *
+ * @author mjayan
+ */
+public class ConvertToNestedRecordPattern {
+
+    private static final int RECORD_PATTERN_PREVIEW_JDK_VERSION = 19;
+
+    @TriggerTreeKind(Tree.Kind.DECONSTRUCTION_PATTERN)
+    public static ErrorDescription convertToNestedRecordPattern(HintContext ctx) {
+        if (Utilities.isJDKVersionLower(RECORD_PATTERN_PREVIEW_JDK_VERSION) && !CompilerOptionsQuery.getOptions(ctx.getInfo().getFileObject()).getArguments().contains("--enable-preview")) {
+            return null;
+        }
+        TreePath t = ctx.getPath();
+        if (!t.getParentPath().getLeaf().getKind().equals(Tree.Kind.INSTANCE_OF)) {
+            return null;
+        }
+        Set<String> recordPatternVarSet = new HashSet<>();
+        Map<PatternTree, List<PatternTree>> recordComponentMap = new LinkedHashMap<>();
+        DeconstructionPatternTree recordPattern = (DeconstructionPatternTree) t.getLeaf();
+        recordComponentMap = findNested(recordPattern, recordComponentMap);
+
+        for (PatternTree p : recordComponentMap.keySet()) {
+            BindingPatternTree bTree = (BindingPatternTree) p;
+            recordPatternVarSet.add(bTree.getVariable().getName().toString());
+        }
+        while (t != null && t.getLeaf().getKind() != Tree.Kind.IF) {
+            t = t.getParentPath();
+        }
+        Set<TreePath> convertPath = new HashSet<>();
+        List<String> localVarList = new ArrayList<>();
+        Map<String, List<UserVariables>> userVars = new HashMap<>();
+        new TreePathScanner<Void, Void>() {
+
+            @Override
+            public Void visitVariable(VariableTree node, Void p) {
+                localVarList.add(node.getName().toString());
+                Map<String, TreePath> outerVariables = new HashMap<>();
+                Map<String, String> innerVariables = new HashMap<>();
+                List<UserVariables> nList = new ArrayList<>();
+                boolean match = MatcherUtilities.matches(ctx, getCurrentPath(), "$type $var1 = $expr3.$meth1()", outerVariables, new HashMap<>(), innerVariables);
+
+                if (match && recordPatternVarSet.contains(outerVariables.get("$expr3").getLeaf().toString())) {
+                    String expr3 = outerVariables.get("$expr3").getLeaf().toString();
+                    nList.clear();
+                    if (userVars.get(expr3) != null) {
+                        nList = userVars.get(expr3);
+                    }
+                    nList.add(new UserVariables(innerVariables.get("$var1"), innerVariables.get("$meth1")));
+                    userVars.put(expr3, nList);
+                    convertPath.add(getCurrentPath());
+                }
+                return super.visitVariable(node, p);
+            }
+        }.scan(t, null);
+        if (!convertPath.isEmpty()) {
+            Fix fix = new FixImpl(ctx.getInfo(), ctx.getPath(), convertPath, localVarList, userVars).toEditorFix();
+            return ErrorDescriptionFactory.forName(ctx, ctx.getPath(), Bundle.ERR_ConvertToNestedRecordPattern(), fix);
+        }
+        return null;
+    }
+
+    private static Map<PatternTree, List<PatternTree>> findNested(PatternTree pTree, Map<PatternTree, List<PatternTree>> recordComponentMap) {
+        if (pTree instanceof BindingPatternTree) {
+            recordComponentMap.put(pTree, new ArrayList<>());
+            return recordComponentMap;
+        } else {
+            DeconstructionPatternTree bTree = (DeconstructionPatternTree) pTree;
+            for (PatternTree p : bTree.getNestedPatterns()) {
+                findNested(p, recordComponentMap);
+            }
+        }
+        return recordComponentMap;
+    }
+
+    private static class UserVariables {
+
+        String methodName;
+        String variable;
+
+        UserVariables(String variable, String methodName) {
+            this.variable = variable;
+            this.methodName = methodName;
+        }
+
+        public String getMethodName() {
+            return methodName;
+        }
+
+        public String getVariable() {
+            return variable;
+        }
+    }
+
+    private static final class FixImpl extends JavaFix {
+
+        private final Map<String, List<UserVariables>> userVars;
+        private final Set<TreePathHandle> replaceOccurrences;
+        List<String> localVarList;
+
+        public FixImpl(CompilationInfo info, TreePath main, Set<TreePath> replaceOccurrences, List<String> localVarList, Map<String, List<UserVariables>> userVars) {
+            super(info, main);
+            this.replaceOccurrences = replaceOccurrences.stream().map(tp -> TreePathHandle.create(tp, info)).collect(Collectors.toSet());
+            this.userVars = userVars;
+            this.localVarList = localVarList;
+        }
+
+        @Override
+        protected String getText() {
+            return Bundle.ERR_ConvertToNestedRecordPattern();
+        }
+
+        @Override
+        protected void performRewrite(JavaFix.TransformationContext ctx) {
+            WorkingCopy wc = ctx.getWorkingCopy();
+            TreePath t = ctx.getPath();
+            TypeElement type = null;
+            Map<PatternTree, List<PatternTree>> recordComponentMap = new LinkedHashMap<>();
+            DeconstructionPatternTree recordPattern = (DeconstructionPatternTree) t.getLeaf();
+            recordComponentMap = findNested(recordPattern, recordComponentMap);
+            
+            Set<String> localVars = new HashSet<>(localVarList);
+            for (PatternTree p : recordComponentMap.keySet()) {
+                List<PatternTree> bindTree = new ArrayList<>();
+                BindingPatternTree bTree = (BindingPatternTree) p;
+                VariableTree v = bTree.getVariable();
+                type = (TypeElement) wc.getTrees().getElement(TreePath.getPath(t, v.getType()));
+                if (type == null || type.getRecordComponents().size() == 0) {
+                    continue;
+                }
+                outer:
+                for (RecordComponentElement recordComponent : type.getRecordComponents()) {
+                    String name = recordComponent.getSimpleName().toString();
+                    String returnType = recordComponent.getAccessor().getReturnType().toString();
+                    returnType = returnType.substring(returnType.lastIndexOf(".") + 1);
+                    if (userVars.get(v.getName().toString()) != null) {
+                        for (UserVariables var : userVars.get(v.getName().toString())) {
+                            if (var.getMethodName().equals(name)) {
+                                bindTree.add((BindingPatternTree) wc.getTreeMaker().BindingPattern(wc.getTreeMaker().Variable(wc.getTreeMaker().
+                                        Modifiers(EnumSet.noneOf(Modifier.class)), var.getVariable(), wc.getTreeMaker().Identifier(returnType), null)));
+                                continue outer;
+                            }
+                        }
+                    }
+                    String baseName = name;
+                    int cnt = 1;
+                    while (SourceVersion.isKeyword(name) || localVars.contains(name)) {
+                        name = CodeStyleUtils.addPrefixSuffix(baseName + cnt++, "", "");
+                    }
+                    localVars.add(name);
+                    bindTree.add((BindingPatternTree) wc.getTreeMaker().BindingPattern(wc.getTreeMaker().Variable(wc.getTreeMaker().
+                            Modifiers(EnumSet.noneOf(Modifier.class)), name, wc.getTreeMaker().Identifier(returnType), null)));
+                }
+                recordComponentMap.put(p, bindTree);
+            }
+
+            DeconstructionPatternTree d = (DeconstructionPatternTree) createNestedPattern((PatternTree) t.getLeaf(), wc, recordComponentMap);
+            while (t != null && t.getLeaf().getKind() != Tree.Kind.IF) {
+                t = t.getParentPath();
+            }
+            IfTree it = (IfTree) t.getLeaf();

Review Comment:
   Please see the comment about searching for the `if` above. If we would search the enclosing block, this may need to be changed to look for immediately enclosing block for the statements we need to remove.
   
   As a note `WorkingCopy.resolveRewriteTarget` might be useful here - even if a tree is re-written several times, this method will return the last rewrite target.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: notifications-unsubscribe@netbeans.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@netbeans.apache.org
For additional commands, e-mail: notifications-help@netbeans.apache.org

For further information about the NetBeans mailing lists, visit:
https://cwiki.apache.org/confluence/display/NETBEANS/Mailing+lists


[GitHub] [netbeans] MegJayan commented on a diff in pull request #4533: Implementation of auto completion, formatting adjustment and providing hints for JEP 405 record patterns

Posted by GitBox <gi...@apache.org>.
MegJayan commented on code in PR #4533:
URL: https://github.com/apache/netbeans/pull/4533#discussion_r997798584


##########
java/java.hints/src/org/netbeans/modules/java/hints/jdk/ConvertToRecordPattern.java:
##########
@@ -0,0 +1,190 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.netbeans.modules.java.hints.jdk;
+
+import com.sun.source.tree.BindingPatternTree;
+import com.sun.source.tree.BlockTree;
+import com.sun.source.tree.ExpressionTree;
+import com.sun.source.tree.IfTree;
+import com.sun.source.tree.InstanceOfTree;
+import com.sun.source.tree.ParenthesizedTree;
+import com.sun.source.tree.PatternTree;
+import com.sun.source.tree.StatementTree;
+import com.sun.source.tree.Tree;
+import com.sun.source.util.TreePath;
+import com.sun.source.util.TreePathScanner;
+import com.sun.source.tree.VariableTree;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.EnumSet;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.stream.Collectors;
+import javax.lang.model.SourceVersion;
+import javax.lang.model.element.ElementKind;
+import javax.lang.model.element.Modifier;
+import javax.lang.model.element.RecordComponentElement;
+import javax.lang.model.element.TypeElement;
+import org.netbeans.api.java.source.CodeStyleUtils;
+import org.netbeans.api.java.source.CompilationInfo;
+import org.netbeans.api.java.source.TreePathHandle;
+import org.netbeans.api.java.source.ElementHandle;
+import org.netbeans.api.java.source.WorkingCopy;
+import org.netbeans.api.java.queries.CompilerOptionsQuery;
+import org.netbeans.modules.java.hints.errors.Utilities;
+import org.netbeans.spi.editor.hints.ErrorDescription;
+import org.netbeans.spi.editor.hints.Fix;
+import org.netbeans.spi.java.hints.ErrorDescriptionFactory;
+import org.netbeans.spi.java.hints.Hint;
+import org.netbeans.spi.java.hints.HintContext;
+import org.netbeans.spi.java.hints.JavaFix;
+import org.netbeans.spi.java.hints.MatcherUtilities;
+import org.netbeans.spi.java.hints.TriggerPattern;
+import org.netbeans.spi.java.hints.TriggerPatterns;
+import org.openide.util.NbBundle;
+
+/**
+ *
+ * @author mjayan
+ */
+@NbBundle.Messages({
+    "DN_ConvertToRecordPattern=Convert to instanceof <record pattern>",
+    "DESC_ConvertToRecordPattern=Convert to instanceof <record pattern>",
+    "ERR_ConvertToRecordPattern=instanceof <record pattern> can be used here",
+    "FIX_ConvertToRecordPattern=Use instanceof <record pattern>"
+})
+@Hint(displayName = "#DN_ConvertToRecordPattern", description = "#DESC_ConvertToRecordPattern", category = "rules15",
+        minSourceVersion = "19")
+public class ConvertToRecordPattern {
+ 
+    private static final int RECORD_PATTERN_PREVIEW_JDK_VERSION = 19;
+
+    @TriggerPatterns({
+        @TriggerPattern(value = "if ($expr instanceof $typeI0 $var0 ) { $statements$;} else $else$;")
+    })
+    public static ErrorDescription trivial(HintContext ctx) {
+        if (Utilities.isJDKVersionLower(RECORD_PATTERN_PREVIEW_JDK_VERSION) && !CompilerOptionsQuery.getOptions(ctx.getInfo().getFileObject()).getArguments().contains("--enable-preview")) {
+            return null;
+        }
+        ElementKind kind = ctx.getInfo().getTrees().getElement(ctx.getVariables().get("$typeI0")).getKind();
+        if (kind.equals(ElementKind.RECORD)) {
+            Set<TreePath> convertPath = new HashSet<>();
+            Set<String> localVarList = new HashSet<>();
+            localVarList.add(ctx.getInfo().getTrees().getElement(ctx.getVariables().get("$expr")).getSimpleName().toString());
+            Map<String, String> varNames = new HashMap<>();
+            new TreePathScanner<Void, Void>() {

Review Comment:
   addressed



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: notifications-unsubscribe@netbeans.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@netbeans.apache.org
For additional commands, e-mail: notifications-help@netbeans.apache.org

For further information about the NetBeans mailing lists, visit:
https://cwiki.apache.org/confluence/display/NETBEANS/Mailing+lists


[GitHub] [netbeans] MegJayan commented on a diff in pull request #4533: Implementation of auto completion, formatting adjustment and providing hints for JEP 405 record patterns

Posted by GitBox <gi...@apache.org>.
MegJayan commented on code in PR #4533:
URL: https://github.com/apache/netbeans/pull/4533#discussion_r996652911


##########
java/java.source.base/src/org/netbeans/modules/java/source/pretty/VeryPretty.java:
##########
@@ -2091,8 +2092,30 @@ public void visitErroneous(JCErroneous tree) {
 
     @Override
     public void visitTree(JCTree tree) {
-	print("(UNKNOWN: " + tree + ")");
-	newline();
+        print("(UNKNOWN: " + tree + ")");
+        newline();
+    }
+    
+    @Override
+    public void visitRecordPattern(JCRecordPattern tree) {
+        print((JCExpression) tree.deconstructor);
+        print("(");
+        Iterator<JCPattern> it = tree.nested.iterator();
+        while (it.hasNext()) {
+            JCPattern pattern = it.next();
+            if (pattern instanceof JCBindingPattern) {

Review Comment:
   @lahodaj : doAccept(pattern, true) takes a pattern of type DocTree right? Is it proper to use this here as we are not dealing with patterns inside documentation syntax tree?



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: notifications-unsubscribe@netbeans.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@netbeans.apache.org
For additional commands, e-mail: notifications-help@netbeans.apache.org

For further information about the NetBeans mailing lists, visit:
https://cwiki.apache.org/confluence/display/NETBEANS/Mailing+lists


[GitHub] [netbeans] lahodaj commented on a diff in pull request #4533: Implementation of auto completion, formatting adjustment and providing hints for JEP 405 record patterns

Posted by GitBox <gi...@apache.org>.
lahodaj commented on code in PR #4533:
URL: https://github.com/apache/netbeans/pull/4533#discussion_r975201608


##########
java/java.source.base/src/org/netbeans/modules/java/source/TreeShims.java:
##########
@@ -60,6 +63,8 @@ public class TreeShims {
 //    public static final String NULL_LITERAL = "NULL_LITERAL"; //NOI18N
 //    public static final String PARENTHESIZED_PATTERN = "PARENTHESIZED_PATTERN"; //NOI18N
 //    public static final String GUARDED_PATTERN = "GUARDED_PATTERN"; //NOI18N
+    public static final String DECONSTRUCTION_PATTERN = "DECONSTRUCTION_PATTERN";

Review Comment:
   Please note that after https://github.com/apache/netbeans/pull/4467, it should be possible to refer to the deconstruction/record patterns directly, without the need for reflection and `TreeShims`.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: notifications-unsubscribe@netbeans.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@netbeans.apache.org
For additional commands, e-mail: notifications-help@netbeans.apache.org

For further information about the NetBeans mailing lists, visit:
https://cwiki.apache.org/confluence/display/NETBEANS/Mailing+lists


[GitHub] [netbeans] MegJayan commented on a diff in pull request #4533: Implementation of auto completion, formatting adjustment and providing hints for JEP 405 record patterns

Posted by GitBox <gi...@apache.org>.
MegJayan commented on code in PR #4533:
URL: https://github.com/apache/netbeans/pull/4533#discussion_r975203297


##########
java/java.source.base/src/org/netbeans/modules/java/source/TreeShims.java:
##########
@@ -60,6 +63,8 @@ public class TreeShims {
 //    public static final String NULL_LITERAL = "NULL_LITERAL"; //NOI18N
 //    public static final String PARENTHESIZED_PATTERN = "PARENTHESIZED_PATTERN"; //NOI18N
 //    public static final String GUARDED_PATTERN = "GUARDED_PATTERN"; //NOI18N
+    public static final String DECONSTRUCTION_PATTERN = "DECONSTRUCTION_PATTERN";

Review Comment:
   > Please note that after #4467, it should be possible to refer to the deconstruction/record patterns directly, without the need for reflection and `TreeShims`.
   
   Hi, yes. Have noticed that. Will commit the latest code in some time



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: notifications-unsubscribe@netbeans.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@netbeans.apache.org
For additional commands, e-mail: notifications-help@netbeans.apache.org

For further information about the NetBeans mailing lists, visit:
https://cwiki.apache.org/confluence/display/NETBEANS/Mailing+lists


[GitHub] [netbeans] MegJayan commented on a diff in pull request #4533: Implementation of auto completion, formatting adjustment and providing hints for JEP 405 record patterns

Posted by GitBox <gi...@apache.org>.
MegJayan commented on code in PR #4533:
URL: https://github.com/apache/netbeans/pull/4533#discussion_r996652911


##########
java/java.source.base/src/org/netbeans/modules/java/source/pretty/VeryPretty.java:
##########
@@ -2091,8 +2092,30 @@ public void visitErroneous(JCErroneous tree) {
 
     @Override
     public void visitTree(JCTree tree) {
-	print("(UNKNOWN: " + tree + ")");
-	newline();
+        print("(UNKNOWN: " + tree + ")");
+        newline();
+    }
+    
+    @Override
+    public void visitRecordPattern(JCRecordPattern tree) {
+        print((JCExpression) tree.deconstructor);
+        print("(");
+        Iterator<JCPattern> it = tree.nested.iterator();
+        while (it.hasNext()) {
+            JCPattern pattern = it.next();
+            if (pattern instanceof JCBindingPattern) {

Review Comment:
   @lahodaj : doAccept(pattern, true) takes a pattern of type DocTree right? Is it proper to use this here as we are not dealing with patterns of type documentation syntax tree?



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: notifications-unsubscribe@netbeans.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@netbeans.apache.org
For additional commands, e-mail: notifications-help@netbeans.apache.org

For further information about the NetBeans mailing lists, visit:
https://cwiki.apache.org/confluence/display/NETBEANS/Mailing+lists


[GitHub] [netbeans] MegJayan commented on a diff in pull request #4533: Implementation of auto completion, formatting adjustment and providing hints for JEP 405 record patterns

Posted by GitBox <gi...@apache.org>.
MegJayan commented on code in PR #4533:
URL: https://github.com/apache/netbeans/pull/4533#discussion_r998184894


##########
java/java.hints/src/org/netbeans/modules/java/hints/jdk/ConvertToNestedRecordPattern.java:
##########
@@ -0,0 +1,261 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.netbeans.modules.java.hints.jdk;
+
+import com.sun.source.tree.BindingPatternTree;
+import com.sun.source.tree.BlockTree;
+import com.sun.source.tree.DeconstructionPatternTree;
+import com.sun.source.tree.ExpressionTree;
+import com.sun.source.tree.IfTree;
+import com.sun.source.tree.InstanceOfTree;
+import com.sun.source.tree.ParenthesizedTree;
+import com.sun.source.tree.PatternTree;
+import com.sun.source.tree.StatementTree;
+import com.sun.source.tree.Tree;
+import com.sun.source.util.TreePath;
+import com.sun.source.tree.VariableTree;
+import com.sun.source.util.TreePathScanner;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.EnumSet;
+import java.util.Map;
+import java.util.Set;
+import java.util.stream.Collectors;
+import javax.lang.model.SourceVersion;
+import javax.lang.model.element.Modifier;
+import javax.lang.model.element.RecordComponentElement;
+import javax.lang.model.element.TypeElement;
+import org.netbeans.api.java.source.CompilationInfo;
+import org.netbeans.api.java.source.TreePathHandle;
+import org.netbeans.api.java.source.CodeStyleUtils;
+import org.netbeans.api.java.source.WorkingCopy;
+import org.netbeans.api.java.queries.CompilerOptionsQuery;
+import org.netbeans.modules.java.hints.errors.Utilities;
+import org.netbeans.spi.editor.hints.ErrorDescription;
+import org.netbeans.spi.editor.hints.Fix;
+import org.netbeans.spi.java.hints.ErrorDescriptionFactory;
+import org.netbeans.spi.java.hints.Hint;
+import org.netbeans.spi.java.hints.HintContext;
+import org.netbeans.spi.java.hints.JavaFix;
+import org.netbeans.spi.java.hints.MatcherUtilities;
+import org.netbeans.spi.java.hints.TriggerTreeKind;
+import org.openide.util.NbBundle;
+
+@NbBundle.Messages({
+    "DN_ConvertToNestedRecordPattern=Convert to nested record pattern",
+    "DESC_ConvertToNestedRecordPattern=Convert to nested record pattern",
+    "ERR_ConvertToNestedRecordPattern=Convert to nested record pattern",
+    "FIX_ConvertToNestedRecordPattern=Convert to nested record pattern"
+})
+@Hint(displayName = "#DN_ConvertToNestedRecordPattern", description = "#DESC_ConvertToNestedRecordPattern", category = "rules15",
+        minSourceVersion = "19")
+/**
+ *
+ * @author mjayan
+ */
+public class ConvertToNestedRecordPattern {
+
+    private static final int RECORD_PATTERN_PREVIEW_JDK_VERSION = 19;
+
+    @TriggerTreeKind(Tree.Kind.DECONSTRUCTION_PATTERN)
+    public static ErrorDescription convertToNestedRecordPattern(HintContext ctx) {
+        if (Utilities.isJDKVersionLower(RECORD_PATTERN_PREVIEW_JDK_VERSION) && !CompilerOptionsQuery.getOptions(ctx.getInfo().getFileObject()).getArguments().contains("--enable-preview")) {
+            return null;
+        }
+        TreePath t = ctx.getPath();
+        if (!t.getParentPath().getLeaf().getKind().equals(Tree.Kind.INSTANCE_OF)) {
+            return null;
+        }
+        Set<String> recordPatternVarSet = new HashSet<>();
+        Map<PatternTree, List<PatternTree>> recordComponentMap = new LinkedHashMap<>();
+        DeconstructionPatternTree recordPattern = (DeconstructionPatternTree) t.getLeaf();
+        recordComponentMap = findNested(recordPattern, recordComponentMap);
+
+        for (PatternTree p : recordComponentMap.keySet()) {
+            BindingPatternTree bTree = (BindingPatternTree) p;
+            recordPatternVarSet.add(bTree.getVariable().getName().toString());
+        }
+        while (t != null && t.getLeaf().getKind() != Tree.Kind.IF) {
+            t = t.getParentPath();
+        }
+        Set<TreePath> convertPath = new HashSet<>();
+        List<String> localVarList = new ArrayList<>();
+        Map<String, List<UserVariables>> userVars = new HashMap<>();
+        new TreePathScanner<Void, Void>() {
+
+            @Override
+            public Void visitVariable(VariableTree node, Void p) {
+                localVarList.add(node.getName().toString());
+                Map<String, TreePath> outerVariables = new HashMap<>();
+                Map<String, String> innerVariables = new HashMap<>();
+                List<UserVariables> nList = new ArrayList<>();
+                boolean match = MatcherUtilities.matches(ctx, getCurrentPath(), "$type $var1 = $expr3.$meth1()", outerVariables, new HashMap<>(), innerVariables);
+
+                if (match && recordPatternVarSet.contains(outerVariables.get("$expr3").getLeaf().toString())) {
+                    String expr3 = outerVariables.get("$expr3").getLeaf().toString();
+                    nList.clear();
+                    if (userVars.get(expr3) != null) {
+                        nList = userVars.get(expr3);
+                    }
+                    nList.add(new UserVariables(innerVariables.get("$var1"), innerVariables.get("$meth1")));
+                    userVars.put(expr3, nList);
+                    convertPath.add(getCurrentPath());
+                }
+                return super.visitVariable(node, p);
+            }
+        }.scan(t, null);
+        if (!convertPath.isEmpty()) {
+            Fix fix = new FixImpl(ctx.getInfo(), ctx.getPath(), convertPath, localVarList, userVars).toEditorFix();
+            return ErrorDescriptionFactory.forName(ctx, ctx.getPath(), Bundle.ERR_ConvertToNestedRecordPattern(), fix);
+        }
+        return null;
+    }
+
+    private static Map<PatternTree, List<PatternTree>> findNested(PatternTree pTree, Map<PatternTree, List<PatternTree>> recordComponentMap) {
+        if (pTree instanceof BindingPatternTree) {
+            recordComponentMap.put(pTree, new ArrayList<>());
+            return recordComponentMap;
+        } else {
+            DeconstructionPatternTree bTree = (DeconstructionPatternTree) pTree;
+            for (PatternTree p : bTree.getNestedPatterns()) {
+                findNested(p, recordComponentMap);
+            }
+        }
+        return recordComponentMap;
+    }
+
+    private static class UserVariables {
+
+        String methodName;
+        String variable;
+
+        UserVariables(String variable, String methodName) {
+            this.variable = variable;
+            this.methodName = methodName;
+        }
+
+        public String getMethodName() {
+            return methodName;
+        }
+
+        public String getVariable() {
+            return variable;
+        }
+    }
+
+    private static final class FixImpl extends JavaFix {
+
+        private final Map<String, List<UserVariables>> userVars;
+        private final Set<TreePathHandle> replaceOccurrences;
+        List<String> localVarList;
+
+        public FixImpl(CompilationInfo info, TreePath main, Set<TreePath> replaceOccurrences, List<String> localVarList, Map<String, List<UserVariables>> userVars) {
+            super(info, main);
+            this.replaceOccurrences = replaceOccurrences.stream().map(tp -> TreePathHandle.create(tp, info)).collect(Collectors.toSet());
+            this.userVars = userVars;
+            this.localVarList = localVarList;
+        }
+
+        @Override
+        protected String getText() {
+            return Bundle.ERR_ConvertToNestedRecordPattern();
+        }
+
+        @Override
+        protected void performRewrite(JavaFix.TransformationContext ctx) {
+            WorkingCopy wc = ctx.getWorkingCopy();
+            TreePath t = ctx.getPath();
+            TypeElement type = null;
+            Map<PatternTree, List<PatternTree>> recordComponentMap = new LinkedHashMap<>();
+            DeconstructionPatternTree recordPattern = (DeconstructionPatternTree) t.getLeaf();
+            recordComponentMap = findNested(recordPattern, recordComponentMap);
+            
+            Set<String> localVars = new HashSet<>(localVarList);
+            for (PatternTree p : recordComponentMap.keySet()) {
+                List<PatternTree> bindTree = new ArrayList<>();
+                BindingPatternTree bTree = (BindingPatternTree) p;
+                VariableTree v = bTree.getVariable();
+                type = (TypeElement) wc.getTrees().getElement(TreePath.getPath(t, v.getType()));
+                if (type == null || type.getRecordComponents().size() == 0) {
+                    continue;
+                }
+                outer:
+                for (RecordComponentElement recordComponent : type.getRecordComponents()) {
+                    String name = recordComponent.getSimpleName().toString();
+                    String returnType = recordComponent.getAccessor().getReturnType().toString();
+                    returnType = returnType.substring(returnType.lastIndexOf(".") + 1);
+                    if (userVars.get(v.getName().toString()) != null) {
+                        for (UserVariables var : userVars.get(v.getName().toString())) {
+                            if (var.getMethodName().equals(name)) {
+                                bindTree.add((BindingPatternTree) wc.getTreeMaker().BindingPattern(wc.getTreeMaker().Variable(wc.getTreeMaker().
+                                        Modifiers(EnumSet.noneOf(Modifier.class)), var.getVariable(), wc.getTreeMaker().Identifier(returnType), null)));
+                                continue outer;
+                            }
+                        }
+                    }
+                    String baseName = name;
+                    int cnt = 1;
+                    while (SourceVersion.isKeyword(name) || localVars.contains(name)) {
+                        name = CodeStyleUtils.addPrefixSuffix(baseName + cnt++, "", "");
+                    }
+                    localVars.add(name);
+                    bindTree.add((BindingPatternTree) wc.getTreeMaker().BindingPattern(wc.getTreeMaker().Variable(wc.getTreeMaker().
+                            Modifiers(EnumSet.noneOf(Modifier.class)), name, wc.getTreeMaker().Identifier(returnType), null)));
+                }
+                recordComponentMap.put(p, bindTree);
+            }
+
+            DeconstructionPatternTree d = (DeconstructionPatternTree) createNestedPattern((PatternTree) t.getLeaf(), wc, recordComponentMap);
+            while (t != null && t.getLeaf().getKind() != Tree.Kind.IF) {
+                t = t.getParentPath();
+            }
+            IfTree it = (IfTree) t.getLeaf();

Review Comment:
   handled by checking for the immediately enclosing block



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: notifications-unsubscribe@netbeans.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@netbeans.apache.org
For additional commands, e-mail: notifications-help@netbeans.apache.org

For further information about the NetBeans mailing lists, visit:
https://cwiki.apache.org/confluence/display/NETBEANS/Mailing+lists


[GitHub] [netbeans] MegJayan commented on a diff in pull request #4533: Implementation of auto completion, formatting adjustment and providing hints for JEP 405 record patterns

Posted by GitBox <gi...@apache.org>.
MegJayan commented on code in PR #4533:
URL: https://github.com/apache/netbeans/pull/4533#discussion_r997800738


##########
java/java.hints/src/org/netbeans/modules/java/hints/jdk/ConvertToNestedRecordPattern.java:
##########
@@ -0,0 +1,261 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.netbeans.modules.java.hints.jdk;
+
+import com.sun.source.tree.BindingPatternTree;
+import com.sun.source.tree.BlockTree;
+import com.sun.source.tree.DeconstructionPatternTree;
+import com.sun.source.tree.ExpressionTree;
+import com.sun.source.tree.IfTree;
+import com.sun.source.tree.InstanceOfTree;
+import com.sun.source.tree.ParenthesizedTree;
+import com.sun.source.tree.PatternTree;
+import com.sun.source.tree.StatementTree;
+import com.sun.source.tree.Tree;
+import com.sun.source.util.TreePath;
+import com.sun.source.tree.VariableTree;
+import com.sun.source.util.TreePathScanner;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.EnumSet;
+import java.util.Map;
+import java.util.Set;
+import java.util.stream.Collectors;
+import javax.lang.model.SourceVersion;
+import javax.lang.model.element.Modifier;
+import javax.lang.model.element.RecordComponentElement;
+import javax.lang.model.element.TypeElement;
+import org.netbeans.api.java.source.CompilationInfo;
+import org.netbeans.api.java.source.TreePathHandle;
+import org.netbeans.api.java.source.CodeStyleUtils;
+import org.netbeans.api.java.source.WorkingCopy;
+import org.netbeans.api.java.queries.CompilerOptionsQuery;
+import org.netbeans.modules.java.hints.errors.Utilities;
+import org.netbeans.spi.editor.hints.ErrorDescription;
+import org.netbeans.spi.editor.hints.Fix;
+import org.netbeans.spi.java.hints.ErrorDescriptionFactory;
+import org.netbeans.spi.java.hints.Hint;
+import org.netbeans.spi.java.hints.HintContext;
+import org.netbeans.spi.java.hints.JavaFix;
+import org.netbeans.spi.java.hints.MatcherUtilities;
+import org.netbeans.spi.java.hints.TriggerTreeKind;
+import org.openide.util.NbBundle;
+
+@NbBundle.Messages({
+    "DN_ConvertToNestedRecordPattern=Convert to nested record pattern",
+    "DESC_ConvertToNestedRecordPattern=Convert to nested record pattern",
+    "ERR_ConvertToNestedRecordPattern=Convert to nested record pattern",
+    "FIX_ConvertToNestedRecordPattern=Convert to nested record pattern"
+})
+@Hint(displayName = "#DN_ConvertToNestedRecordPattern", description = "#DESC_ConvertToNestedRecordPattern", category = "rules15",
+        minSourceVersion = "19")
+/**
+ *
+ * @author mjayan
+ */
+public class ConvertToNestedRecordPattern {
+
+    private static final int RECORD_PATTERN_PREVIEW_JDK_VERSION = 19;
+
+    @TriggerTreeKind(Tree.Kind.DECONSTRUCTION_PATTERN)
+    public static ErrorDescription convertToNestedRecordPattern(HintContext ctx) {
+        if (Utilities.isJDKVersionLower(RECORD_PATTERN_PREVIEW_JDK_VERSION) && !CompilerOptionsQuery.getOptions(ctx.getInfo().getFileObject()).getArguments().contains("--enable-preview")) {
+            return null;
+        }
+        TreePath t = ctx.getPath();
+        if (!t.getParentPath().getLeaf().getKind().equals(Tree.Kind.INSTANCE_OF)) {
+            return null;
+        }
+        Set<String> recordPatternVarSet = new HashSet<>();
+        Map<PatternTree, List<PatternTree>> recordComponentMap = new LinkedHashMap<>();
+        DeconstructionPatternTree recordPattern = (DeconstructionPatternTree) t.getLeaf();
+        recordComponentMap = findNested(recordPattern, recordComponentMap);
+
+        for (PatternTree p : recordComponentMap.keySet()) {
+            BindingPatternTree bTree = (BindingPatternTree) p;
+            recordPatternVarSet.add(bTree.getVariable().getName().toString());
+        }
+        while (t != null && t.getLeaf().getKind() != Tree.Kind.IF) {
+            t = t.getParentPath();
+        }
+        Set<TreePath> convertPath = new HashSet<>();
+        List<String> localVarList = new ArrayList<>();
+        Map<String, List<UserVariables>> userVars = new HashMap<>();
+        new TreePathScanner<Void, Void>() {
+
+            @Override
+            public Void visitVariable(VariableTree node, Void p) {
+                localVarList.add(node.getName().toString());
+                Map<String, TreePath> outerVariables = new HashMap<>();
+                Map<String, String> innerVariables = new HashMap<>();
+                List<UserVariables> nList = new ArrayList<>();
+                boolean match = MatcherUtilities.matches(ctx, getCurrentPath(), "$type $var1 = $expr3.$meth1()", outerVariables, new HashMap<>(), innerVariables);
+
+                if (match && recordPatternVarSet.contains(outerVariables.get("$expr3").getLeaf().toString())) {
+                    String expr3 = outerVariables.get("$expr3").getLeaf().toString();
+                    nList.clear();
+                    if (userVars.get(expr3) != null) {
+                        nList = userVars.get(expr3);
+                    }
+                    nList.add(new UserVariables(innerVariables.get("$var1"), innerVariables.get("$meth1")));
+                    userVars.put(expr3, nList);
+                    convertPath.add(getCurrentPath());
+                }
+                return super.visitVariable(node, p);
+            }
+        }.scan(t, null);
+        if (!convertPath.isEmpty()) {
+            Fix fix = new FixImpl(ctx.getInfo(), ctx.getPath(), convertPath, localVarList, userVars).toEditorFix();
+            return ErrorDescriptionFactory.forName(ctx, ctx.getPath(), Bundle.ERR_ConvertToNestedRecordPattern(), fix);
+        }
+        return null;
+    }
+
+    private static Map<PatternTree, List<PatternTree>> findNested(PatternTree pTree, Map<PatternTree, List<PatternTree>> recordComponentMap) {
+        if (pTree instanceof BindingPatternTree) {
+            recordComponentMap.put(pTree, new ArrayList<>());
+            return recordComponentMap;
+        } else {
+            DeconstructionPatternTree bTree = (DeconstructionPatternTree) pTree;
+            for (PatternTree p : bTree.getNestedPatterns()) {
+                findNested(p, recordComponentMap);
+            }
+        }
+        return recordComponentMap;
+    }
+
+    private static class UserVariables {
+
+        String methodName;
+        String variable;
+
+        UserVariables(String variable, String methodName) {
+            this.variable = variable;
+            this.methodName = methodName;
+        }
+
+        public String getMethodName() {
+            return methodName;
+        }
+
+        public String getVariable() {
+            return variable;
+        }
+    }
+
+    private static final class FixImpl extends JavaFix {
+
+        private final Map<String, List<UserVariables>> userVars;
+        private final Set<TreePathHandle> replaceOccurrences;
+        List<String> localVarList;
+
+        public FixImpl(CompilationInfo info, TreePath main, Set<TreePath> replaceOccurrences, List<String> localVarList, Map<String, List<UserVariables>> userVars) {
+            super(info, main);
+            this.replaceOccurrences = replaceOccurrences.stream().map(tp -> TreePathHandle.create(tp, info)).collect(Collectors.toSet());
+            this.userVars = userVars;
+            this.localVarList = localVarList;
+        }
+
+        @Override
+        protected String getText() {
+            return Bundle.ERR_ConvertToNestedRecordPattern();
+        }
+
+        @Override
+        protected void performRewrite(JavaFix.TransformationContext ctx) {
+            WorkingCopy wc = ctx.getWorkingCopy();
+            TreePath t = ctx.getPath();
+            TypeElement type = null;
+            Map<PatternTree, List<PatternTree>> recordComponentMap = new LinkedHashMap<>();
+            DeconstructionPatternTree recordPattern = (DeconstructionPatternTree) t.getLeaf();
+            recordComponentMap = findNested(recordPattern, recordComponentMap);
+            
+            Set<String> localVars = new HashSet<>(localVarList);
+            for (PatternTree p : recordComponentMap.keySet()) {
+                List<PatternTree> bindTree = new ArrayList<>();
+                BindingPatternTree bTree = (BindingPatternTree) p;
+                VariableTree v = bTree.getVariable();
+                type = (TypeElement) wc.getTrees().getElement(TreePath.getPath(t, v.getType()));
+                if (type == null || type.getRecordComponents().size() == 0) {
+                    continue;
+                }
+                outer:
+                for (RecordComponentElement recordComponent : type.getRecordComponents()) {
+                    String name = recordComponent.getSimpleName().toString();
+                    String returnType = recordComponent.getAccessor().getReturnType().toString();
+                    returnType = returnType.substring(returnType.lastIndexOf(".") + 1);

Review Comment:
   addressed



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: notifications-unsubscribe@netbeans.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@netbeans.apache.org
For additional commands, e-mail: notifications-help@netbeans.apache.org

For further information about the NetBeans mailing lists, visit:
https://cwiki.apache.org/confluence/display/NETBEANS/Mailing+lists


[GitHub] [netbeans] MegJayan commented on a diff in pull request #4533: Implementation of auto completion, formatting adjustment and providing hints for JEP 405 record patterns

Posted by GitBox <gi...@apache.org>.
MegJayan commented on code in PR #4533:
URL: https://github.com/apache/netbeans/pull/4533#discussion_r997800436


##########
java/java.hints/src/org/netbeans/modules/java/hints/jdk/ConvertToNestedRecordPattern.java:
##########
@@ -0,0 +1,261 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.netbeans.modules.java.hints.jdk;
+
+import com.sun.source.tree.BindingPatternTree;
+import com.sun.source.tree.BlockTree;
+import com.sun.source.tree.DeconstructionPatternTree;
+import com.sun.source.tree.ExpressionTree;
+import com.sun.source.tree.IfTree;
+import com.sun.source.tree.InstanceOfTree;
+import com.sun.source.tree.ParenthesizedTree;
+import com.sun.source.tree.PatternTree;
+import com.sun.source.tree.StatementTree;
+import com.sun.source.tree.Tree;
+import com.sun.source.util.TreePath;
+import com.sun.source.tree.VariableTree;
+import com.sun.source.util.TreePathScanner;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.EnumSet;
+import java.util.Map;
+import java.util.Set;
+import java.util.stream.Collectors;
+import javax.lang.model.SourceVersion;
+import javax.lang.model.element.Modifier;
+import javax.lang.model.element.RecordComponentElement;
+import javax.lang.model.element.TypeElement;
+import org.netbeans.api.java.source.CompilationInfo;
+import org.netbeans.api.java.source.TreePathHandle;
+import org.netbeans.api.java.source.CodeStyleUtils;
+import org.netbeans.api.java.source.WorkingCopy;
+import org.netbeans.api.java.queries.CompilerOptionsQuery;
+import org.netbeans.modules.java.hints.errors.Utilities;
+import org.netbeans.spi.editor.hints.ErrorDescription;
+import org.netbeans.spi.editor.hints.Fix;
+import org.netbeans.spi.java.hints.ErrorDescriptionFactory;
+import org.netbeans.spi.java.hints.Hint;
+import org.netbeans.spi.java.hints.HintContext;
+import org.netbeans.spi.java.hints.JavaFix;
+import org.netbeans.spi.java.hints.MatcherUtilities;
+import org.netbeans.spi.java.hints.TriggerTreeKind;
+import org.openide.util.NbBundle;
+
+@NbBundle.Messages({
+    "DN_ConvertToNestedRecordPattern=Convert to nested record pattern",
+    "DESC_ConvertToNestedRecordPattern=Convert to nested record pattern",
+    "ERR_ConvertToNestedRecordPattern=Convert to nested record pattern",
+    "FIX_ConvertToNestedRecordPattern=Convert to nested record pattern"
+})
+@Hint(displayName = "#DN_ConvertToNestedRecordPattern", description = "#DESC_ConvertToNestedRecordPattern", category = "rules15",
+        minSourceVersion = "19")
+/**
+ *
+ * @author mjayan
+ */
+public class ConvertToNestedRecordPattern {
+
+    private static final int RECORD_PATTERN_PREVIEW_JDK_VERSION = 19;
+
+    @TriggerTreeKind(Tree.Kind.DECONSTRUCTION_PATTERN)
+    public static ErrorDescription convertToNestedRecordPattern(HintContext ctx) {
+        if (Utilities.isJDKVersionLower(RECORD_PATTERN_PREVIEW_JDK_VERSION) && !CompilerOptionsQuery.getOptions(ctx.getInfo().getFileObject()).getArguments().contains("--enable-preview")) {
+            return null;
+        }
+        TreePath t = ctx.getPath();
+        if (!t.getParentPath().getLeaf().getKind().equals(Tree.Kind.INSTANCE_OF)) {
+            return null;
+        }
+        Set<String> recordPatternVarSet = new HashSet<>();
+        Map<PatternTree, List<PatternTree>> recordComponentMap = new LinkedHashMap<>();
+        DeconstructionPatternTree recordPattern = (DeconstructionPatternTree) t.getLeaf();
+        recordComponentMap = findNested(recordPattern, recordComponentMap);
+
+        for (PatternTree p : recordComponentMap.keySet()) {
+            BindingPatternTree bTree = (BindingPatternTree) p;
+            recordPatternVarSet.add(bTree.getVariable().getName().toString());
+        }
+        while (t != null && t.getLeaf().getKind() != Tree.Kind.IF) {
+            t = t.getParentPath();
+        }
+        Set<TreePath> convertPath = new HashSet<>();
+        List<String> localVarList = new ArrayList<>();
+        Map<String, List<UserVariables>> userVars = new HashMap<>();
+        new TreePathScanner<Void, Void>() {
+
+            @Override
+            public Void visitVariable(VariableTree node, Void p) {
+                localVarList.add(node.getName().toString());
+                Map<String, TreePath> outerVariables = new HashMap<>();
+                Map<String, String> innerVariables = new HashMap<>();
+                List<UserVariables> nList = new ArrayList<>();
+                boolean match = MatcherUtilities.matches(ctx, getCurrentPath(), "$type $var1 = $expr3.$meth1()", outerVariables, new HashMap<>(), innerVariables);
+
+                if (match && recordPatternVarSet.contains(outerVariables.get("$expr3").getLeaf().toString())) {
+                    String expr3 = outerVariables.get("$expr3").getLeaf().toString();
+                    nList.clear();
+                    if (userVars.get(expr3) != null) {
+                        nList = userVars.get(expr3);
+                    }
+                    nList.add(new UserVariables(innerVariables.get("$var1"), innerVariables.get("$meth1")));
+                    userVars.put(expr3, nList);
+                    convertPath.add(getCurrentPath());
+                }
+                return super.visitVariable(node, p);
+            }
+        }.scan(t, null);
+        if (!convertPath.isEmpty()) {
+            Fix fix = new FixImpl(ctx.getInfo(), ctx.getPath(), convertPath, localVarList, userVars).toEditorFix();
+            return ErrorDescriptionFactory.forName(ctx, ctx.getPath(), Bundle.ERR_ConvertToNestedRecordPattern(), fix);
+        }
+        return null;
+    }
+
+    private static Map<PatternTree, List<PatternTree>> findNested(PatternTree pTree, Map<PatternTree, List<PatternTree>> recordComponentMap) {
+        if (pTree instanceof BindingPatternTree) {
+            recordComponentMap.put(pTree, new ArrayList<>());
+            return recordComponentMap;
+        } else {
+            DeconstructionPatternTree bTree = (DeconstructionPatternTree) pTree;

Review Comment:
   added case for parenthesized and default label



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: notifications-unsubscribe@netbeans.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@netbeans.apache.org
For additional commands, e-mail: notifications-help@netbeans.apache.org

For further information about the NetBeans mailing lists, visit:
https://cwiki.apache.org/confluence/display/NETBEANS/Mailing+lists


[GitHub] [netbeans] MegJayan commented on a diff in pull request #4533: Implementation of auto completion, formatting adjustment and providing hints for JEP 405 record patterns

Posted by GitBox <gi...@apache.org>.
MegJayan commented on code in PR #4533:
URL: https://github.com/apache/netbeans/pull/4533#discussion_r997796407


##########
java/java.hints/src/org/netbeans/modules/java/hints/jdk/ConvertToNestedRecordPattern.java:
##########
@@ -0,0 +1,261 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.netbeans.modules.java.hints.jdk;
+
+import com.sun.source.tree.BindingPatternTree;
+import com.sun.source.tree.BlockTree;
+import com.sun.source.tree.DeconstructionPatternTree;
+import com.sun.source.tree.ExpressionTree;
+import com.sun.source.tree.IfTree;
+import com.sun.source.tree.InstanceOfTree;
+import com.sun.source.tree.ParenthesizedTree;
+import com.sun.source.tree.PatternTree;
+import com.sun.source.tree.StatementTree;
+import com.sun.source.tree.Tree;
+import com.sun.source.util.TreePath;
+import com.sun.source.tree.VariableTree;
+import com.sun.source.util.TreePathScanner;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.EnumSet;
+import java.util.Map;
+import java.util.Set;
+import java.util.stream.Collectors;
+import javax.lang.model.SourceVersion;
+import javax.lang.model.element.Modifier;
+import javax.lang.model.element.RecordComponentElement;
+import javax.lang.model.element.TypeElement;
+import org.netbeans.api.java.source.CompilationInfo;
+import org.netbeans.api.java.source.TreePathHandle;
+import org.netbeans.api.java.source.CodeStyleUtils;
+import org.netbeans.api.java.source.WorkingCopy;
+import org.netbeans.api.java.queries.CompilerOptionsQuery;
+import org.netbeans.modules.java.hints.errors.Utilities;
+import org.netbeans.spi.editor.hints.ErrorDescription;
+import org.netbeans.spi.editor.hints.Fix;
+import org.netbeans.spi.java.hints.ErrorDescriptionFactory;
+import org.netbeans.spi.java.hints.Hint;
+import org.netbeans.spi.java.hints.HintContext;
+import org.netbeans.spi.java.hints.JavaFix;
+import org.netbeans.spi.java.hints.MatcherUtilities;
+import org.netbeans.spi.java.hints.TriggerTreeKind;
+import org.openide.util.NbBundle;
+
+@NbBundle.Messages({
+    "DN_ConvertToNestedRecordPattern=Convert to nested record pattern",
+    "DESC_ConvertToNestedRecordPattern=Convert to nested record pattern",
+    "ERR_ConvertToNestedRecordPattern=Convert to nested record pattern",
+    "FIX_ConvertToNestedRecordPattern=Convert to nested record pattern"
+})
+@Hint(displayName = "#DN_ConvertToNestedRecordPattern", description = "#DESC_ConvertToNestedRecordPattern", category = "rules15",
+        minSourceVersion = "19")
+/**
+ *
+ * @author mjayan
+ */
+public class ConvertToNestedRecordPattern {
+
+    private static final int RECORD_PATTERN_PREVIEW_JDK_VERSION = 19;
+
+    @TriggerTreeKind(Tree.Kind.DECONSTRUCTION_PATTERN)
+    public static ErrorDescription convertToNestedRecordPattern(HintContext ctx) {
+        if (Utilities.isJDKVersionLower(RECORD_PATTERN_PREVIEW_JDK_VERSION) && !CompilerOptionsQuery.getOptions(ctx.getInfo().getFileObject()).getArguments().contains("--enable-preview")) {
+            return null;
+        }
+        TreePath t = ctx.getPath();
+        if (!t.getParentPath().getLeaf().getKind().equals(Tree.Kind.INSTANCE_OF)) {
+            return null;
+        }
+        Set<String> recordPatternVarSet = new HashSet<>();
+        Map<PatternTree, List<PatternTree>> recordComponentMap = new LinkedHashMap<>();
+        DeconstructionPatternTree recordPattern = (DeconstructionPatternTree) t.getLeaf();
+        recordComponentMap = findNested(recordPattern, recordComponentMap);
+
+        for (PatternTree p : recordComponentMap.keySet()) {
+            BindingPatternTree bTree = (BindingPatternTree) p;
+            recordPatternVarSet.add(bTree.getVariable().getName().toString());
+        }
+        while (t != null && t.getLeaf().getKind() != Tree.Kind.IF) {
+            t = t.getParentPath();
+        }
+        Set<TreePath> convertPath = new HashSet<>();
+        List<String> localVarList = new ArrayList<>();
+        Map<String, List<UserVariables>> userVars = new HashMap<>();
+        new TreePathScanner<Void, Void>() {

Review Comment:
   addressed



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: notifications-unsubscribe@netbeans.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@netbeans.apache.org
For additional commands, e-mail: notifications-help@netbeans.apache.org

For further information about the NetBeans mailing lists, visit:
https://cwiki.apache.org/confluence/display/NETBEANS/Mailing+lists


[GitHub] [netbeans] MegJayan commented on a diff in pull request #4533: Implementation of auto completion, formatting adjustment and providing hints for JEP 405 record patterns

Posted by GitBox <gi...@apache.org>.
MegJayan commented on code in PR #4533:
URL: https://github.com/apache/netbeans/pull/4533#discussion_r997795305


##########
java/java.source.base/src/org/netbeans/modules/java/source/pretty/VeryPretty.java:
##########
@@ -2091,8 +2092,30 @@ public void visitErroneous(JCErroneous tree) {
 
     @Override
     public void visitTree(JCTree tree) {
-	print("(UNKNOWN: " + tree + ")");
-	newline();
+        print("(UNKNOWN: " + tree + ")");
+        newline();
+    }
+    
+    @Override
+    public void visitRecordPattern(JCRecordPattern tree) {
+        print((JCExpression) tree.deconstructor);
+        print("(");
+        Iterator<JCPattern> it = tree.nested.iterator();
+        while (it.hasNext()) {
+            JCPattern pattern = it.next();
+            if (pattern instanceof JCBindingPattern) {

Review Comment:
   addressed



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: notifications-unsubscribe@netbeans.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@netbeans.apache.org
For additional commands, e-mail: notifications-help@netbeans.apache.org

For further information about the NetBeans mailing lists, visit:
https://cwiki.apache.org/confluence/display/NETBEANS/Mailing+lists


[GitHub] [netbeans] MegJayan commented on a diff in pull request #4533: Implementation of auto completion, formatting adjustment and providing hints for JEP 405 record patterns

Posted by GitBox <gi...@apache.org>.
MegJayan commented on code in PR #4533:
URL: https://github.com/apache/netbeans/pull/4533#discussion_r997799394


##########
java/java.hints/src/org/netbeans/modules/java/hints/jdk/ConvertToNestedRecordPattern.java:
##########
@@ -0,0 +1,261 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.netbeans.modules.java.hints.jdk;
+
+import com.sun.source.tree.BindingPatternTree;
+import com.sun.source.tree.BlockTree;
+import com.sun.source.tree.DeconstructionPatternTree;
+import com.sun.source.tree.ExpressionTree;
+import com.sun.source.tree.IfTree;
+import com.sun.source.tree.InstanceOfTree;
+import com.sun.source.tree.ParenthesizedTree;
+import com.sun.source.tree.PatternTree;
+import com.sun.source.tree.StatementTree;
+import com.sun.source.tree.Tree;
+import com.sun.source.util.TreePath;
+import com.sun.source.tree.VariableTree;
+import com.sun.source.util.TreePathScanner;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.EnumSet;
+import java.util.Map;
+import java.util.Set;
+import java.util.stream.Collectors;
+import javax.lang.model.SourceVersion;
+import javax.lang.model.element.Modifier;
+import javax.lang.model.element.RecordComponentElement;
+import javax.lang.model.element.TypeElement;
+import org.netbeans.api.java.source.CompilationInfo;
+import org.netbeans.api.java.source.TreePathHandle;
+import org.netbeans.api.java.source.CodeStyleUtils;
+import org.netbeans.api.java.source.WorkingCopy;
+import org.netbeans.api.java.queries.CompilerOptionsQuery;
+import org.netbeans.modules.java.hints.errors.Utilities;
+import org.netbeans.spi.editor.hints.ErrorDescription;
+import org.netbeans.spi.editor.hints.Fix;
+import org.netbeans.spi.java.hints.ErrorDescriptionFactory;
+import org.netbeans.spi.java.hints.Hint;
+import org.netbeans.spi.java.hints.HintContext;
+import org.netbeans.spi.java.hints.JavaFix;
+import org.netbeans.spi.java.hints.MatcherUtilities;
+import org.netbeans.spi.java.hints.TriggerTreeKind;
+import org.openide.util.NbBundle;
+
+@NbBundle.Messages({
+    "DN_ConvertToNestedRecordPattern=Convert to nested record pattern",
+    "DESC_ConvertToNestedRecordPattern=Convert to nested record pattern",
+    "ERR_ConvertToNestedRecordPattern=Convert to nested record pattern",
+    "FIX_ConvertToNestedRecordPattern=Convert to nested record pattern"
+})
+@Hint(displayName = "#DN_ConvertToNestedRecordPattern", description = "#DESC_ConvertToNestedRecordPattern", category = "rules15",
+        minSourceVersion = "19")
+/**
+ *
+ * @author mjayan
+ */
+public class ConvertToNestedRecordPattern {
+
+    private static final int RECORD_PATTERN_PREVIEW_JDK_VERSION = 19;
+
+    @TriggerTreeKind(Tree.Kind.DECONSTRUCTION_PATTERN)
+    public static ErrorDescription convertToNestedRecordPattern(HintContext ctx) {
+        if (Utilities.isJDKVersionLower(RECORD_PATTERN_PREVIEW_JDK_VERSION) && !CompilerOptionsQuery.getOptions(ctx.getInfo().getFileObject()).getArguments().contains("--enable-preview")) {
+            return null;
+        }
+        TreePath t = ctx.getPath();
+        if (!t.getParentPath().getLeaf().getKind().equals(Tree.Kind.INSTANCE_OF)) {
+            return null;
+        }
+        Set<String> recordPatternVarSet = new HashSet<>();
+        Map<PatternTree, List<PatternTree>> recordComponentMap = new LinkedHashMap<>();
+        DeconstructionPatternTree recordPattern = (DeconstructionPatternTree) t.getLeaf();
+        recordComponentMap = findNested(recordPattern, recordComponentMap);
+
+        for (PatternTree p : recordComponentMap.keySet()) {
+            BindingPatternTree bTree = (BindingPatternTree) p;
+            recordPatternVarSet.add(bTree.getVariable().getName().toString());
+        }
+        while (t != null && t.getLeaf().getKind() != Tree.Kind.IF) {
+            t = t.getParentPath();
+        }
+        Set<TreePath> convertPath = new HashSet<>();
+        List<String> localVarList = new ArrayList<>();
+        Map<String, List<UserVariables>> userVars = new HashMap<>();
+        new TreePathScanner<Void, Void>() {
+
+            @Override
+            public Void visitVariable(VariableTree node, Void p) {
+                localVarList.add(node.getName().toString());
+                Map<String, TreePath> outerVariables = new HashMap<>();
+                Map<String, String> innerVariables = new HashMap<>();
+                List<UserVariables> nList = new ArrayList<>();
+                boolean match = MatcherUtilities.matches(ctx, getCurrentPath(), "$type $var1 = $expr3.$meth1()", outerVariables, new HashMap<>(), innerVariables);
+
+                if (match && recordPatternVarSet.contains(outerVariables.get("$expr3").getLeaf().toString())) {
+                    String expr3 = outerVariables.get("$expr3").getLeaf().toString();
+                    nList.clear();
+                    if (userVars.get(expr3) != null) {
+                        nList = userVars.get(expr3);
+                    }
+                    nList.add(new UserVariables(innerVariables.get("$var1"), innerVariables.get("$meth1")));
+                    userVars.put(expr3, nList);
+                    convertPath.add(getCurrentPath());
+                }
+                return super.visitVariable(node, p);
+            }
+        }.scan(t, null);
+        if (!convertPath.isEmpty()) {
+            Fix fix = new FixImpl(ctx.getInfo(), ctx.getPath(), convertPath, localVarList, userVars).toEditorFix();
+            return ErrorDescriptionFactory.forName(ctx, ctx.getPath(), Bundle.ERR_ConvertToNestedRecordPattern(), fix);
+        }
+        return null;
+    }
+
+    private static Map<PatternTree, List<PatternTree>> findNested(PatternTree pTree, Map<PatternTree, List<PatternTree>> recordComponentMap) {
+        if (pTree instanceof BindingPatternTree) {
+            recordComponentMap.put(pTree, new ArrayList<>());
+            return recordComponentMap;
+        } else {
+            DeconstructionPatternTree bTree = (DeconstructionPatternTree) pTree;
+            for (PatternTree p : bTree.getNestedPatterns()) {
+                findNested(p, recordComponentMap);
+            }
+        }
+        return recordComponentMap;
+    }
+
+    private static class UserVariables {
+
+        String methodName;
+        String variable;
+
+        UserVariables(String variable, String methodName) {
+            this.variable = variable;
+            this.methodName = methodName;
+        }
+
+        public String getMethodName() {
+            return methodName;
+        }
+
+        public String getVariable() {
+            return variable;
+        }
+    }
+
+    private static final class FixImpl extends JavaFix {
+
+        private final Map<String, List<UserVariables>> userVars;
+        private final Set<TreePathHandle> replaceOccurrences;
+        List<String> localVarList;
+
+        public FixImpl(CompilationInfo info, TreePath main, Set<TreePath> replaceOccurrences, List<String> localVarList, Map<String, List<UserVariables>> userVars) {
+            super(info, main);
+            this.replaceOccurrences = replaceOccurrences.stream().map(tp -> TreePathHandle.create(tp, info)).collect(Collectors.toSet());
+            this.userVars = userVars;
+            this.localVarList = localVarList;
+        }
+
+        @Override
+        protected String getText() {
+            return Bundle.ERR_ConvertToNestedRecordPattern();
+        }
+
+        @Override
+        protected void performRewrite(JavaFix.TransformationContext ctx) {
+            WorkingCopy wc = ctx.getWorkingCopy();
+            TreePath t = ctx.getPath();
+            TypeElement type = null;
+            Map<PatternTree, List<PatternTree>> recordComponentMap = new LinkedHashMap<>();
+            DeconstructionPatternTree recordPattern = (DeconstructionPatternTree) t.getLeaf();
+            recordComponentMap = findNested(recordPattern, recordComponentMap);
+            
+            Set<String> localVars = new HashSet<>(localVarList);
+            for (PatternTree p : recordComponentMap.keySet()) {
+                List<PatternTree> bindTree = new ArrayList<>();
+                BindingPatternTree bTree = (BindingPatternTree) p;
+                VariableTree v = bTree.getVariable();
+                type = (TypeElement) wc.getTrees().getElement(TreePath.getPath(t, v.getType()));
+                if (type == null || type.getRecordComponents().size() == 0) {
+                    continue;
+                }
+                outer:
+                for (RecordComponentElement recordComponent : type.getRecordComponents()) {
+                    String name = recordComponent.getSimpleName().toString();
+                    String returnType = recordComponent.getAccessor().getReturnType().toString();
+                    returnType = returnType.substring(returnType.lastIndexOf(".") + 1);
+                    if (userVars.get(v.getName().toString()) != null) {
+                        for (UserVariables var : userVars.get(v.getName().toString())) {
+                            if (var.getMethodName().equals(name)) {
+                                bindTree.add((BindingPatternTree) wc.getTreeMaker().BindingPattern(wc.getTreeMaker().Variable(wc.getTreeMaker().
+                                        Modifiers(EnumSet.noneOf(Modifier.class)), var.getVariable(), wc.getTreeMaker().Identifier(returnType), null)));
+                                continue outer;
+                            }
+                        }
+                    }
+                    String baseName = name;
+                    int cnt = 1;
+                    while (SourceVersion.isKeyword(name) || localVars.contains(name)) {
+                        name = CodeStyleUtils.addPrefixSuffix(baseName + cnt++, "", "");
+                    }
+                    localVars.add(name);
+                    bindTree.add((BindingPatternTree) wc.getTreeMaker().BindingPattern(wc.getTreeMaker().Variable(wc.getTreeMaker().
+                            Modifiers(EnumSet.noneOf(Modifier.class)), name, wc.getTreeMaker().Identifier(returnType), null)));
+                }
+                recordComponentMap.put(p, bindTree);
+            }
+
+            DeconstructionPatternTree d = (DeconstructionPatternTree) createNestedPattern((PatternTree) t.getLeaf(), wc, recordComponentMap);
+            while (t != null && t.getLeaf().getKind() != Tree.Kind.IF) {
+                t = t.getParentPath();
+            }
+            IfTree it = (IfTree) t.getLeaf();
+            InstanceOfTree iot = (InstanceOfTree) ((ParenthesizedTree) it.getCondition()).getExpression();
+            StatementTree bt = it.getThenStatement();
+            InstanceOfTree cond = wc.getTreeMaker().InstanceOf(iot.getExpression(), d);
+            List<Tree> removeList = replaceOccurrences.stream().map(tph -> tph.resolve(wc).getLeaf()).collect(Collectors.toList());
+            for(Tree tree : removeList) {
+                bt = wc.getTreeMaker().removeBlockStatement((BlockTree) bt, (StatementTree) tree);
+            }
+            wc.rewrite(it, wc.getTreeMaker().If(wc.getTreeMaker().Parenthesized(cond), bt, it.getElseStatement()));
+        }
+    }
+
+    private static PatternTree createNestedPattern(PatternTree pTree, WorkingCopy wc, Map<PatternTree, List<PatternTree>> map) {
+        if (pTree instanceof BindingPatternTree) {

Review Comment:
   addressed, modified to use switch case



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: notifications-unsubscribe@netbeans.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@netbeans.apache.org
For additional commands, e-mail: notifications-help@netbeans.apache.org

For further information about the NetBeans mailing lists, visit:
https://cwiki.apache.org/confluence/display/NETBEANS/Mailing+lists


[GitHub] [netbeans] MegJayan commented on a diff in pull request #4533: Implementation of auto completion, formatting adjustment and providing hints for JEP 405 record patterns

Posted by GitBox <gi...@apache.org>.
MegJayan commented on code in PR #4533:
URL: https://github.com/apache/netbeans/pull/4533#discussion_r997799744


##########
java/java.hints/src/org/netbeans/modules/java/hints/jdk/ConvertToNestedRecordPattern.java:
##########
@@ -0,0 +1,261 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.netbeans.modules.java.hints.jdk;
+
+import com.sun.source.tree.BindingPatternTree;
+import com.sun.source.tree.BlockTree;
+import com.sun.source.tree.DeconstructionPatternTree;
+import com.sun.source.tree.ExpressionTree;
+import com.sun.source.tree.IfTree;
+import com.sun.source.tree.InstanceOfTree;
+import com.sun.source.tree.ParenthesizedTree;
+import com.sun.source.tree.PatternTree;
+import com.sun.source.tree.StatementTree;
+import com.sun.source.tree.Tree;
+import com.sun.source.util.TreePath;
+import com.sun.source.tree.VariableTree;
+import com.sun.source.util.TreePathScanner;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.EnumSet;
+import java.util.Map;
+import java.util.Set;
+import java.util.stream.Collectors;
+import javax.lang.model.SourceVersion;
+import javax.lang.model.element.Modifier;
+import javax.lang.model.element.RecordComponentElement;
+import javax.lang.model.element.TypeElement;
+import org.netbeans.api.java.source.CompilationInfo;
+import org.netbeans.api.java.source.TreePathHandle;
+import org.netbeans.api.java.source.CodeStyleUtils;
+import org.netbeans.api.java.source.WorkingCopy;
+import org.netbeans.api.java.queries.CompilerOptionsQuery;
+import org.netbeans.modules.java.hints.errors.Utilities;
+import org.netbeans.spi.editor.hints.ErrorDescription;
+import org.netbeans.spi.editor.hints.Fix;
+import org.netbeans.spi.java.hints.ErrorDescriptionFactory;
+import org.netbeans.spi.java.hints.Hint;
+import org.netbeans.spi.java.hints.HintContext;
+import org.netbeans.spi.java.hints.JavaFix;
+import org.netbeans.spi.java.hints.MatcherUtilities;
+import org.netbeans.spi.java.hints.TriggerTreeKind;
+import org.openide.util.NbBundle;
+
+@NbBundle.Messages({
+    "DN_ConvertToNestedRecordPattern=Convert to nested record pattern",
+    "DESC_ConvertToNestedRecordPattern=Convert to nested record pattern",
+    "ERR_ConvertToNestedRecordPattern=Convert to nested record pattern",
+    "FIX_ConvertToNestedRecordPattern=Convert to nested record pattern"
+})
+@Hint(displayName = "#DN_ConvertToNestedRecordPattern", description = "#DESC_ConvertToNestedRecordPattern", category = "rules15",
+        minSourceVersion = "19")
+/**
+ *
+ * @author mjayan
+ */
+public class ConvertToNestedRecordPattern {
+
+    private static final int RECORD_PATTERN_PREVIEW_JDK_VERSION = 19;
+
+    @TriggerTreeKind(Tree.Kind.DECONSTRUCTION_PATTERN)
+    public static ErrorDescription convertToNestedRecordPattern(HintContext ctx) {
+        if (Utilities.isJDKVersionLower(RECORD_PATTERN_PREVIEW_JDK_VERSION) && !CompilerOptionsQuery.getOptions(ctx.getInfo().getFileObject()).getArguments().contains("--enable-preview")) {
+            return null;
+        }
+        TreePath t = ctx.getPath();
+        if (!t.getParentPath().getLeaf().getKind().equals(Tree.Kind.INSTANCE_OF)) {
+            return null;
+        }
+        Set<String> recordPatternVarSet = new HashSet<>();
+        Map<PatternTree, List<PatternTree>> recordComponentMap = new LinkedHashMap<>();
+        DeconstructionPatternTree recordPattern = (DeconstructionPatternTree) t.getLeaf();
+        recordComponentMap = findNested(recordPattern, recordComponentMap);
+
+        for (PatternTree p : recordComponentMap.keySet()) {
+            BindingPatternTree bTree = (BindingPatternTree) p;
+            recordPatternVarSet.add(bTree.getVariable().getName().toString());
+        }
+        while (t != null && t.getLeaf().getKind() != Tree.Kind.IF) {
+            t = t.getParentPath();
+        }
+        Set<TreePath> convertPath = new HashSet<>();
+        List<String> localVarList = new ArrayList<>();
+        Map<String, List<UserVariables>> userVars = new HashMap<>();
+        new TreePathScanner<Void, Void>() {
+
+            @Override
+            public Void visitVariable(VariableTree node, Void p) {
+                localVarList.add(node.getName().toString());
+                Map<String, TreePath> outerVariables = new HashMap<>();
+                Map<String, String> innerVariables = new HashMap<>();
+                List<UserVariables> nList = new ArrayList<>();
+                boolean match = MatcherUtilities.matches(ctx, getCurrentPath(), "$type $var1 = $expr3.$meth1()", outerVariables, new HashMap<>(), innerVariables);
+
+                if (match && recordPatternVarSet.contains(outerVariables.get("$expr3").getLeaf().toString())) {
+                    String expr3 = outerVariables.get("$expr3").getLeaf().toString();
+                    nList.clear();
+                    if (userVars.get(expr3) != null) {
+                        nList = userVars.get(expr3);
+                    }
+                    nList.add(new UserVariables(innerVariables.get("$var1"), innerVariables.get("$meth1")));
+                    userVars.put(expr3, nList);
+                    convertPath.add(getCurrentPath());
+                }
+                return super.visitVariable(node, p);
+            }
+        }.scan(t, null);
+        if (!convertPath.isEmpty()) {
+            Fix fix = new FixImpl(ctx.getInfo(), ctx.getPath(), convertPath, localVarList, userVars).toEditorFix();
+            return ErrorDescriptionFactory.forName(ctx, ctx.getPath(), Bundle.ERR_ConvertToNestedRecordPattern(), fix);
+        }
+        return null;
+    }
+
+    private static Map<PatternTree, List<PatternTree>> findNested(PatternTree pTree, Map<PatternTree, List<PatternTree>> recordComponentMap) {
+        if (pTree instanceof BindingPatternTree) {

Review Comment:
   handled



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: notifications-unsubscribe@netbeans.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@netbeans.apache.org
For additional commands, e-mail: notifications-help@netbeans.apache.org

For further information about the NetBeans mailing lists, visit:
https://cwiki.apache.org/confluence/display/NETBEANS/Mailing+lists


[GitHub] [netbeans] singh-akhilesh merged pull request #4533: Implementation of auto completion, formatting adjustment and providing hints for JEP 405 record patterns

Posted by GitBox <gi...@apache.org>.
singh-akhilesh merged PR #4533:
URL: https://github.com/apache/netbeans/pull/4533


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: notifications-unsubscribe@netbeans.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@netbeans.apache.org
For additional commands, e-mail: notifications-help@netbeans.apache.org

For further information about the NetBeans mailing lists, visit:
https://cwiki.apache.org/confluence/display/NETBEANS/Mailing+lists


[GitHub] [netbeans] MegJayan commented on a diff in pull request #4533: Implementation of auto completion, formatting adjustment and providing hints for JEP 405 record patterns

Posted by GitBox <gi...@apache.org>.
MegJayan commented on code in PR #4533:
URL: https://github.com/apache/netbeans/pull/4533#discussion_r998184122


##########
java/java.hints/test/unit/src/org/netbeans/modules/java/hints/jdk/ConvertToNestedRecordPatternTest.java:
##########
@@ -0,0 +1,159 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.netbeans.modules.java.hints.jdk;
+
+import org.netbeans.junit.NbTestCase;
+import org.netbeans.modules.java.hints.test.api.HintTest;
+import javax.lang.model.SourceVersion;
+
+/**
+ *
+ * @author mjayan
+ */
+public class ConvertToNestedRecordPatternTest extends NbTestCase {
+
+    public ConvertToNestedRecordPatternTest(String name) {
+        super(name);
+    }
+
+    public void testSimple() throws Exception {
+        if (!isRecordClassPresent()) {
+            return;
+        }
+        HintTest.create()
+                .input("package test;\n"
+                        + "record Rect(ColoredPoint upperLeft,ColoredPoint lr) {}\n"
+                        + "record ColoredPoint(Point p, Color c) {}\n"
+                        + "record Point(int x, int y){}\n"
+                        + "enum Color {RED,GREEN,BLUE}\n"
+                        + "public class Test {\n"
+                        + "    private void test(Object o) {\n"
+                        + "        if (o instanceof Rect(ColoredPoint ul, ColoredPoint lr)) {\n"

Review Comment:
   this will be handled as part of JDK 20 changes



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: notifications-unsubscribe@netbeans.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@netbeans.apache.org
For additional commands, e-mail: notifications-help@netbeans.apache.org

For further information about the NetBeans mailing lists, visit:
https://cwiki.apache.org/confluence/display/NETBEANS/Mailing+lists