This is an automated email from the ASF dual-hosted git repository.

akhileshsingh pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/netbeans.git


The following commit(s) were added to refs/heads/master by this push:
     new 6beddee262 Implementation of auto completion, formatting adjustment 
and providing hints for JEP 405 record patterns (#4533)
6beddee262 is described below

commit 6beddee262e8bdf6f2d0f94b2085a797d85dc23f
Author: Meghna Jayan <meghna.ja...@oracle.com>
AuthorDate: Wed Oct 19 12:48:13 2022 +0530

    Implementation of auto completion, formatting adjustment and providing 
hints for JEP 405 record patterns (#4533)
    
    * Add autocompletion for Record Patterns
---
 .../java/completion/JavaCompletionTask.java        |  26 +-
 .../1.8/AutoCompletion_RecordPattern_1.pass        |   1 +
 .../1.8/AutoCompletion_RecordPattern_2.pass        |   1 +
 .../1.8/AutoCompletion_RecordPattern_3.pass        |   1 +
 .../19/AutoCompletion_RecordPattern_1.pass         |   1 +
 .../19/AutoCompletion_RecordPattern_2.pass         |   1 +
 .../19/AutoCompletion_RecordPattern_3.pass         |   1 +
 .../java/completion/data/RecordPattern.java        |  44 ++++
 .../java/completion/CompletionTestBase.java        |  30 ++-
 .../JavaCompletionTask119FeaturesTest.java         |  26 +-
 .../modules/editor/java/JavaCompletionItem.java    |  55 +++-
 .../editor/java/JavaCompletionItemFactory.java     |   8 +-
 .../hints/jdk/ConvertToNestedRecordPattern.java    | 278 +++++++++++++++++++++
 .../java/hints/jdk/ConvertToRecordPattern.java     | 194 ++++++++++++++
 .../jdk/ConvertToNestedRecordPatternTest.java      | 159 ++++++++++++
 .../java/hints/jdk/ConvertToRecordPatternTest.java | 145 +++++++++++
 .../org/netbeans/api/java/source/TreeMaker.java    |  13 +
 .../netbeans/modules/java/source/TreeShims.java    |  58 +++++
 .../modules/java/source/pretty/VeryPretty.java     |  23 +-
 .../modules/java/source/save/CasualDiff.java       |  26 ++
 .../modules/java/source/save/Reformatter.java      |   4 +-
 .../modules/java/source/save/FormatingTest.java    | 177 +++++++++++++
 22 files changed, 1259 insertions(+), 13 deletions(-)

diff --git 
a/java/java.completion/src/org/netbeans/modules/java/completion/JavaCompletionTask.java
 
b/java/java.completion/src/org/netbeans/modules/java/completion/JavaCompletionTask.java
index 422efaa3c1..d4298e774f 100644
--- 
a/java/java.completion/src/org/netbeans/modules/java/completion/JavaCompletionTask.java
+++ 
b/java/java.completion/src/org/netbeans/modules/java/completion/JavaCompletionTask.java
@@ -130,6 +130,10 @@ public final class JavaCompletionTask<T> extends BaseTask {
         T createModuleItem(String moduleName, int substitutionOffset);
     }
 
+    public static interface RecordPatternItemFactory<T> extends ItemFactory<T> 
{
+        T createRecordPatternItem(CompilationInfo info, TypeElement elem, 
DeclaredType type, int substitutionOffset, ReferencesCount referencesCount, 
boolean isDeprecated, boolean insideNew, boolean addTypeVars);
+    }
+
     public static enum Options {
 
         ALL_COMPLETION,
@@ -493,6 +497,9 @@ public final class JavaCompletionTask<T> extends BaseTask {
                 localResult(env);
                 addKeywordsForBlock(env);
                 break;
+            case DECONSTRUCTION_PATTERN:
+                insideDeconstructionRecordPattern(env);
+                break;
             case PARENTHESIZED_PATTERN:
                 insideParenthesizedPattern(env);
                 break;
@@ -3250,6 +3257,16 @@ public final class JavaCompletionTask<T> extends 
BaseTask {
 
     }
 
+    private void insideDeconstructionRecordPattern(final Env env) throws 
IOException {
+        final CompilationController controller = env.getController();
+        final Elements elements = controller.getElements();
+        TypeMirror tm = 
controller.getTreeUtilities().parseType(env.getPrefix(), 
env.getScope().getEnclosingClass());
+        TypeElement e = (TypeElement) ((DeclaredType) tm).asElement();
+        if (e.getSimpleName().toString().contentEquals(env.getPrefix()) && 
(e.getKind().equals(ElementKind.RECORD))) {
+            results.add(((RecordPatternItemFactory<T>) 
itemFactory).createRecordPatternItem(env.getController(), e, (DeclaredType) 
e.asType(), anchorOffset, null, elements.isDeprecated(e), env.isInsideNew(), 
env.isInsideNew() || env.isInsideClass()));
+        }
+    }
+
     private void insideParenthesizedPattern(Env env) {
         final int offset = env.getOffset();
         final CompilationController controller = env.getController();
@@ -4234,7 +4251,14 @@ public final class JavaCompletionTask<T> extends 
BaseTask {
             }
         };
         for (TypeElement e : 
controller.getElementUtilities().getGlobalTypes(acceptor)) {
-            results.add(itemFactory.createTypeItem(env.getController(), e, 
(DeclaredType) e.asType(), anchorOffset, null, elements.isDeprecated(e), 
env.isInsideNew(), env.isInsideNew() || env.isInsideClass(), false, false, 
false));
+            Tree iot = env.getPath().getLeaf();
+            TokenSequence<JavaTokenId> ts = findLastNonWhitespaceToken(env, 
iot, env.getOffset());
+            if (env.getPrefix() != null && 
e.getSimpleName().toString().contentEquals(env.getPrefix()) && 
(e.getKind().equals(ElementKind.RECORD))
+                    && ts != null && ts.token().id() == 
JavaTokenId.INSTANCEOF) {
+                results.add(((RecordPatternItemFactory<T>) 
itemFactory).createRecordPatternItem(controller, e, (DeclaredType) e.asType(), 
anchorOffset, null, controller.getElements().isDeprecated(e), 
env.isInsideNew(), env.isInsideNew() || env.isInsideClass()));
+            } else {
+                results.add(itemFactory.createTypeItem(env.getController(), e, 
(DeclaredType) e.asType(), anchorOffset, null, elements.isDeprecated(e), 
env.isInsideNew(), env.isInsideNew() || env.isInsideClass(), false, false, 
false));
+            }
         }
     }
 
diff --git 
a/java/java.completion/test/unit/data/goldenfiles/org/netbeans/modules/java/completion/JavaCompletionTaskTest/1.8/AutoCompletion_RecordPattern_1.pass
 
b/java/java.completion/test/unit/data/goldenfiles/org/netbeans/modules/java/completion/JavaCompletionTaskTest/1.8/AutoCompletion_RecordPattern_1.pass
new file mode 100644
index 0000000000..6daf41cb8c
--- /dev/null
+++ 
b/java/java.completion/test/unit/data/goldenfiles/org/netbeans/modules/java/completion/JavaCompletionTaskTest/1.8/AutoCompletion_RecordPattern_1.pass
@@ -0,0 +1 @@
+Person(String name, int a)
\ No newline at end of file
diff --git 
a/java/java.completion/test/unit/data/goldenfiles/org/netbeans/modules/java/completion/JavaCompletionTaskTest/1.8/AutoCompletion_RecordPattern_2.pass
 
b/java/java.completion/test/unit/data/goldenfiles/org/netbeans/modules/java/completion/JavaCompletionTaskTest/1.8/AutoCompletion_RecordPattern_2.pass
new file mode 100644
index 0000000000..a1346a9156
--- /dev/null
+++ 
b/java/java.completion/test/unit/data/goldenfiles/org/netbeans/modules/java/completion/JavaCompletionTaskTest/1.8/AutoCompletion_RecordPattern_2.pass
@@ -0,0 +1 @@
+Rect(ColoredPoint upperLeft, ColoredPoint lr)
\ No newline at end of file
diff --git 
a/java/java.completion/test/unit/data/goldenfiles/org/netbeans/modules/java/completion/JavaCompletionTaskTest/1.8/AutoCompletion_RecordPattern_3.pass
 
b/java/java.completion/test/unit/data/goldenfiles/org/netbeans/modules/java/completion/JavaCompletionTaskTest/1.8/AutoCompletion_RecordPattern_3.pass
new file mode 100644
index 0000000000..3cd138f22b
--- /dev/null
+++ 
b/java/java.completion/test/unit/data/goldenfiles/org/netbeans/modules/java/completion/JavaCompletionTaskTest/1.8/AutoCompletion_RecordPattern_3.pass
@@ -0,0 +1 @@
+ColoredPoint(Point p, Color c)
\ No newline at end of file
diff --git 
a/java/java.completion/test/unit/data/goldenfiles/org/netbeans/modules/java/completion/JavaCompletionTaskTest/19/AutoCompletion_RecordPattern_1.pass
 
b/java/java.completion/test/unit/data/goldenfiles/org/netbeans/modules/java/completion/JavaCompletionTaskTest/19/AutoCompletion_RecordPattern_1.pass
new file mode 100644
index 0000000000..6daf41cb8c
--- /dev/null
+++ 
b/java/java.completion/test/unit/data/goldenfiles/org/netbeans/modules/java/completion/JavaCompletionTaskTest/19/AutoCompletion_RecordPattern_1.pass
@@ -0,0 +1 @@
+Person(String name, int a)
\ No newline at end of file
diff --git 
a/java/java.completion/test/unit/data/goldenfiles/org/netbeans/modules/java/completion/JavaCompletionTaskTest/19/AutoCompletion_RecordPattern_2.pass
 
b/java/java.completion/test/unit/data/goldenfiles/org/netbeans/modules/java/completion/JavaCompletionTaskTest/19/AutoCompletion_RecordPattern_2.pass
new file mode 100644
index 0000000000..a1346a9156
--- /dev/null
+++ 
b/java/java.completion/test/unit/data/goldenfiles/org/netbeans/modules/java/completion/JavaCompletionTaskTest/19/AutoCompletion_RecordPattern_2.pass
@@ -0,0 +1 @@
+Rect(ColoredPoint upperLeft, ColoredPoint lr)
\ No newline at end of file
diff --git 
a/java/java.completion/test/unit/data/goldenfiles/org/netbeans/modules/java/completion/JavaCompletionTaskTest/19/AutoCompletion_RecordPattern_3.pass
 
b/java/java.completion/test/unit/data/goldenfiles/org/netbeans/modules/java/completion/JavaCompletionTaskTest/19/AutoCompletion_RecordPattern_3.pass
new file mode 100644
index 0000000000..3cd138f22b
--- /dev/null
+++ 
b/java/java.completion/test/unit/data/goldenfiles/org/netbeans/modules/java/completion/JavaCompletionTaskTest/19/AutoCompletion_RecordPattern_3.pass
@@ -0,0 +1 @@
+ColoredPoint(Point p, Color c)
\ No newline at end of file
diff --git 
a/java/java.completion/test/unit/data/org/netbeans/modules/java/completion/data/RecordPattern.java
 
b/java/java.completion/test/unit/data/org/netbeans/modules/java/completion/data/RecordPattern.java
new file mode 100644
index 0000000000..1cc92ac252
--- /dev/null
+++ 
b/java/java.completion/test/unit/data/org/netbeans/modules/java/completion/data/RecordPattern.java
@@ -0,0 +1,44 @@
+/*
+ * 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.
+ */
+
+/**
+ *
+ * @author mjayan
+ */
+public class RecordPattern {  
+    public void op(Object o) {
+        if(o instanceof Person) {
+            System.out.println("Hello");
+        }
+        if(o instanceof Rect r){
+            System.out.println("Hy");
+        }
+        if(o instanceof Rect(ColoredPoint upperLeft,ColoredPoint lr)){
+            System.out.println("Hy");
+        }
+    }
+}
+record Person(String name, int a) {}
+record Point(int x, int y) {}
+record Check(int x, String y) {}
+record Rect(ColoredPoint upperLeft,ColoredPoint lr) {}
+record ColoredPoint(Point p, Color c) {}
+enum Color {
+       RED,GREEN,BLUE
+    }
diff --git 
a/java/java.completion/test/unit/src/org/netbeans/modules/java/completion/CompletionTestBase.java
 
b/java/java.completion/test/unit/src/org/netbeans/modules/java/completion/CompletionTestBase.java
index 73247b09bd..fdba908c90 100644
--- 
a/java/java.completion/test/unit/src/org/netbeans/modules/java/completion/CompletionTestBase.java
+++ 
b/java/java.completion/test/unit/src/org/netbeans/modules/java/completion/CompletionTestBase.java
@@ -112,7 +112,7 @@ public class CompletionTestBase extends 
CompletionTestBaseBase {
         LifecycleManager.getDefault().saveAll();
     }
 
-    private static class CIFactory implements 
JavaCompletionTask.ModuleItemFactory<CI> {
+    private static class CIFactory implements 
JavaCompletionTask.ModuleItemFactory<CI>, 
JavaCompletionTask.RecordPatternItemFactory<CI> {
 
         private static final int SMART_TYPE = 1000;
         @Override
@@ -438,6 +438,34 @@ public class CompletionTestBase extends 
CompletionTestBaseBase {
             String simpleName = elem.getSimpleName().toString();
             return new CI(simpleName + "()", smartType ? 650 - SMART_TYPE : 
650, simpleName + "#0#");
         }
+        
+        @Override
+        public CI createRecordPatternItem(CompilationInfo info, TypeElement 
elem, DeclaredType type, int substitutionOffset, ReferencesCount 
referencesCount, boolean isDeprecated, boolean insideNew, boolean addTypeVars) {
+            String simpleName = elem.getSimpleName().toString();
+            StringBuilder sb = new StringBuilder();
+            StringBuilder sortParams = new StringBuilder();
+            sb.append(simpleName);
+            sb.append('(');
+            sortParams.append('(');
+            Iterator<? extends RecordComponentElement> it = 
elem.getRecordComponents().iterator();
+            RecordComponentElement recordComponent;
+            String name;
+            int cnt = 0;
+            while (it.hasNext()) {
+                recordComponent = it.next();
+                name = 
recordComponent.getAccessor().getReturnType().toString();
+                sortParams.append(name);
+                sb.append(name.substring(name.lastIndexOf(".") + 1));
+                sb.append(" ");
+                sb.append(recordComponent.getSimpleName().toString());
+                if (it.hasNext()) {
+                    sb.append(", "); //NOI18N
+                }
+                cnt++;
+            }
+            sb.append(")");
+            return new CI(sb.toString(), 650, "#" + ((cnt < 10 ? "0" : "") + 
cnt) + "#" + sortParams.toString());
+        }
 
         @Override
         public CI createParametersItem(CompilationInfo info, ExecutableElement 
elem, ExecutableType type, int substitutionOffset, boolean isDeprecated, int 
activeParamIndex, String name) {
diff --git 
a/java/java.completion/test/unit/src/org/netbeans/modules/java/completion/JavaCompletionTask119FeaturesTest.java
 
b/java/java.completion/test/unit/src/org/netbeans/modules/java/completion/JavaCompletionTask119FeaturesTest.java
index 231bee5eff..5cb9fecfa4 100644
--- 
a/java/java.completion/test/unit/src/org/netbeans/modules/java/completion/JavaCompletionTask119FeaturesTest.java
+++ 
b/java/java.completion/test/unit/src/org/netbeans/modules/java/completion/JavaCompletionTask119FeaturesTest.java
@@ -1,4 +1,3 @@
-package org.netbeans.modules.java.completion;
 /*
  * Licensed to the Apache Software Foundation (ASF) under one
  * or more contributor license agreements.  See the NOTICE file
@@ -17,7 +16,7 @@ package org.netbeans.modules.java.completion;
  * specific language governing permissions and limitations
  * under the License.
  */
-
+package org.netbeans.modules.java.completion;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -51,6 +50,24 @@ public class JavaCompletionTask119FeaturesTest extends 
CompletionTestBase {
         return suite;
     }
 
+    public void testRecordPatternCompletion_1() throws Exception {
+        
TestCompilerOptionsQueryImplementation.EXTRA_OPTIONS.add("--enable-preview");
+        performTest("RecordPattern", 930, null, 
"AutoCompletion_RecordPattern_1.pass", getLatestSource());
+    }
+
+    public void testRecordPatternCompletion_2() throws Exception {
+        
TestCompilerOptionsQueryImplementation.EXTRA_OPTIONS.add("--enable-preview");
+        performTest("RecordPattern", 1013, null, 
"AutoCompletion_RecordPattern_2.pass", getLatestSource());
+    }
+
+    public void testRecordPatternCompletion_3() throws Exception {
+        
TestCompilerOptionsQueryImplementation.EXTRA_OPTIONS.add("--enable-preview");
+        performTest("RecordPattern", 1107, null, 
"AutoCompletion_RecordPattern_3.pass", getLatestSource());
+    }
+
+    private String getLatestSource() {
+        return 
SourceVersion.latest().name().substring(SourceVersion.latest().name().indexOf("_")
 + 1);
+    }
 
     public void testCasePatternGuard_1() throws Exception {
         
TestCompilerOptionsQueryImplementation.EXTRA_OPTIONS.add("--enable-preview");
@@ -69,12 +86,9 @@ public class JavaCompletionTask119FeaturesTest extends 
CompletionTestBase {
         JavacParser.DISABLE_SOURCE_LEVEL_DOWNGRADE = true;
     }
 
-    private String getLatestSource() {
-        return 
SourceVersion.latest().name().substring(SourceVersion.latest().name().indexOf("_")+1);
-    }
-
     @ServiceProvider(service = CompilerOptionsQueryImplementation.class, 
position = 100)
     public static class TestCompilerOptionsQueryImplementation implements 
CompilerOptionsQueryImplementation {
+
         private static final List<String> EXTRA_OPTIONS = new ArrayList<>();
 
         @Override
diff --git 
a/java/java.editor/src/org/netbeans/modules/editor/java/JavaCompletionItem.java 
b/java/java.editor/src/org/netbeans/modules/editor/java/JavaCompletionItem.java
index 1b7f7d3015..aa52558e64 100644
--- 
a/java/java.editor/src/org/netbeans/modules/editor/java/JavaCompletionItem.java
+++ 
b/java/java.editor/src/org/netbeans/modules/editor/java/JavaCompletionItem.java
@@ -128,6 +128,15 @@ public abstract class JavaCompletionItem implements 
CompletionItem {
         }
     }
 
+    public static JavaCompletionItem createRecordPatternItem(CompilationInfo 
info, TypeElement elem, DeclaredType type, int substitutionOffset, 
ReferencesCount referencesCount, boolean isDeprecated, boolean insideNew, 
boolean addTypeVars) {
+        if(elem.getKind().equals(ElementKind.RECORD)) {
+            return new RecordPatternItem(info, elem, type, 0, 
substitutionOffset, referencesCount, isDeprecated, insideNew);
+        }
+        else {
+            throw new IllegalArgumentException("kind=" + elem.getKind());
+        }
+    }
+
     public static JavaCompletionItem createArrayItem(CompilationInfo info, 
ArrayType type, int substitutionOffset, ReferencesCount referencesCount, 
Elements elements, WhiteListQuery.WhiteList whiteList) {
         int dim = 0;
         TypeMirror tm = type;
@@ -1336,7 +1345,51 @@ public abstract class JavaCompletionItem implements 
CompletionItem {
             return icon;
         }
     }
-    
+
+    static class RecordPatternItem extends ClassItem {
+
+        private String simpleName;
+        private String recordParams;
+
+        private RecordPatternItem(CompilationInfo info, TypeElement elem, 
DeclaredType type, int dim, int substitutionOffset, ReferencesCount 
referencesCount, boolean isDeprecated, boolean insideNew) {
+            super(info, elem, type, dim, substitutionOffset, referencesCount, 
isDeprecated, insideNew, false, false, false, false, null);
+            simpleName = elem.getSimpleName().toString();
+            Iterator<? extends RecordComponentElement> it = 
elem.getRecordComponents().iterator();
+            StringBuilder sb = new StringBuilder();
+            RecordComponentElement recordComponent;
+            String name;
+            sb.append("(");
+            while (it.hasNext()) {
+                recordComponent = it.next();
+                name = 
recordComponent.getAccessor().getReturnType().toString();
+                name = name.substring(name.lastIndexOf(".") + 1);
+                sb.append(name);
+                sb.append(" ");
+                sb.append(recordComponent.getSimpleName().toString());
+                if (it.hasNext()) {
+                    sb.append(", "); //NOI18N
+                }
+            }
+            sb.append(")");
+            recordParams = sb.toString();
+        }
+
+        @Override
+        protected CharSequence substituteText(final JTextComponent c, final 
int offset, final int length, final CharSequence text, final CharSequence 
toAdd) {
+            return recordParams;
+        }
+
+        @Override
+        protected String getLeftHtmlText() {
+            return simpleName + recordParams;
+        }
+
+        @Override
+        public int getSortPriority() {
+            return 650;
+        }
+    }
+
     static class AnnotationTypeItem extends ClassItem {
 
         private static final String ANNOTATION = 
"org/netbeans/modules/editor/resources/completion/annotation_type.png"; // 
NOI18N
diff --git 
a/java/java.editor/src/org/netbeans/modules/editor/java/JavaCompletionItemFactory.java
 
b/java/java.editor/src/org/netbeans/modules/editor/java/JavaCompletionItemFactory.java
index 535a555dfb..41836d865f 100644
--- 
a/java/java.editor/src/org/netbeans/modules/editor/java/JavaCompletionItemFactory.java
+++ 
b/java/java.editor/src/org/netbeans/modules/editor/java/JavaCompletionItemFactory.java
@@ -48,7 +48,8 @@ import org.openide.filesystems.FileObject;
  */
 public final class JavaCompletionItemFactory implements 
JavaCompletionTask.TypeCastableItemFactory<JavaCompletionItem>,
         JavaCompletionTask.LambdaItemFactory<JavaCompletionItem>,
-        JavaCompletionTask.ModuleItemFactory<JavaCompletionItem> {
+        JavaCompletionTask.ModuleItemFactory<JavaCompletionItem>,
+        JavaCompletionTask.RecordPatternItemFactory<JavaCompletionItem> {
 
     private final WhiteListQuery.WhiteList whiteList;
 
@@ -180,4 +181,9 @@ public final class JavaCompletionItemFactory implements 
JavaCompletionTask.TypeC
     public JavaCompletionItem createLambdaItem(CompilationInfo info, 
TypeElement elem, DeclaredType type, int substitutionOffset, boolean 
expression, boolean addSemicolon) {
         return JavaCompletionItem.createLambdaItem(info, elem, type, 
substitutionOffset, expression, addSemicolon);
     }
+
+    @Override
+    public JavaCompletionItem createRecordPatternItem(CompilationInfo info, 
TypeElement elem, DeclaredType type, int substitutionOffset, ReferencesCount 
referencesCount, boolean isDeprecated, boolean insideNew, boolean addTypeVars) {
+        return JavaCompletionItem.createRecordPatternItem(info, elem, type, 
substitutionOffset, referencesCount, isDeprecated, insideNew, addTypeVars);
+    }
 }
diff --git 
a/java/java.hints/src/org/netbeans/modules/java/hints/jdk/ConvertToNestedRecordPattern.java
 
b/java/java.hints/src/org/netbeans/modules/java/hints/jdk/ConvertToNestedRecordPattern.java
new file mode 100644
index 0000000000..cc2d539e02
--- /dev/null
+++ 
b/java/java.hints/src/org/netbeans/modules/java/hints/jdk/ConvertToNestedRecordPattern.java
@@ -0,0 +1,278 @@
+/*
+ * 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.ParenthesizedPatternTree;
+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.tree.CaseTree;
+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 javax.lang.model.type.TypeMirror;
+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.api.java.source.support.CancellableTreePathScanner;
+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.BLOCK) {
+            t = t.getParentPath();
+        }
+        Set<TreePath> convertPath = new HashSet<>();
+        List<String> localVarList = new ArrayList<>();
+        Map<String, List<UserVariables>> userVars = new HashMap<>();
+        new CancellableTreePathScanner<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);
+            }
+
+            @Override
+            protected boolean isCanceled() {
+                return ctx.isCanceled();
+            }
+        }.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) {
+        switch (pTree.getKind()) {
+            case BINDING_PATTERN:
+                recordComponentMap.put(pTree, new ArrayList<>());
+                return recordComponentMap;
+            case DECONSTRUCTION_PATTERN:
+                DeconstructionPatternTree bTree = (DeconstructionPatternTree) 
pTree;
+                for (PatternTree p : bTree.getNestedPatterns()) {
+                    findNested(p, recordComponentMap);
+                }
+                break;
+            case PARENTHESIZED_PATTERN:
+                ParenthesizedPatternTree parenthTree = 
(ParenthesizedPatternTree) pTree;
+                findNested(parenthTree.getPattern(), recordComponentMap);
+                break;
+            default:
+                return 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();
+                    TypeMirror returnType = 
recordComponent.getAccessor().getReturnType();
+                    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().Type(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().Type(returnType), null)));
+                }
+                recordComponentMap.put(p, bindTree);
+            }
+
+            DeconstructionPatternTree d = (DeconstructionPatternTree) 
createNestedPattern((PatternTree) t.getLeaf(), wc, recordComponentMap);
+            while (t != null && t.getLeaf().getKind() != Tree.Kind.BLOCK) {
+                t = t.getParentPath();
+            }
+
+            List<Tree> removeList = replaceOccurrences.stream().map(tph -> 
tph.resolve(wc).getLeaf()).collect(Collectors.toList());
+            for (Tree tree : removeList) {
+                StatementTree statementTree = (StatementTree) tree;
+                Utilities.removeStatements(wc, TreePath.getPath(t, 
statementTree), null);
+            }
+            wc.rewrite(ctx.getPath().getLeaf(), d);
+        }
+    }
+
+    private static PatternTree createNestedPattern(PatternTree pTree, 
WorkingCopy wc, Map<PatternTree, List<PatternTree>> map) {
+        switch (pTree.getKind()) {
+            case BINDING_PATTERN:
+                if (map.containsKey(pTree) && !map.get(pTree).isEmpty()) {
+                    BindingPatternTree p = (BindingPatternTree) pTree;
+                    VariableTree v = (VariableTree) p.getVariable();
+                    return (DeconstructionPatternTree) 
wc.getTreeMaker().RecordPattern((ExpressionTree) v.getType(), map.get(pTree), 
v);
+                } else {
+                    return pTree;
+                }
+            case DECONSTRUCTION_PATTERN:
+                DeconstructionPatternTree bTree = (DeconstructionPatternTree) 
pTree;
+                List<PatternTree> list = new ArrayList<>();
+                for (PatternTree p : bTree.getNestedPatterns()) {
+                    PatternTree val = createNestedPattern(p, wc, map);
+                    list.add(val);
+                }
+                return (DeconstructionPatternTree) 
wc.getTreeMaker().RecordPattern(bTree.getDeconstructor(), list, 
bTree.getVariable());
+            case PARENTHESIZED_PATTERN:
+                ParenthesizedPatternTree parenthTree = 
(ParenthesizedPatternTree) pTree;
+                return createNestedPattern(parenthTree.getPattern(), wc, map);
+            default:
+                return pTree;
+        }
+    }
+}
diff --git 
a/java/java.hints/src/org/netbeans/modules/java/hints/jdk/ConvertToRecordPattern.java
 
b/java/java.hints/src/org/netbeans/modules/java/hints/jdk/ConvertToRecordPattern.java
new file mode 100644
index 0000000000..5ead0e6785
--- /dev/null
+++ 
b/java/java.hints/src/org/netbeans/modules/java/hints/jdk/ConvertToRecordPattern.java
@@ -0,0 +1,194 @@
+/*
+ * 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.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.api.java.source.support.CancellableTreePathScanner;
+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 CancellableTreePathScanner<Void, Void>() {
+                String variableName = null;
+
+                @Override
+                public Void visitVariable(VariableTree node, Void p) {
+                    if (variableName == null) {
+                        variableName = node.getName().toString();
+                    }
+                    localVarList.add(node.getName().toString());
+                    Map<String, TreePath> outerVariables = new HashMap<>();
+                    Map<String, String> innerVariables = new HashMap<>();
+                    boolean match = MatcherUtilities.matches(ctx, 
getCurrentPath(), "$type $var1 = $expr3.$meth1()", outerVariables, new 
HashMap<String, Collection<? extends TreePath>>(), innerVariables);
+
+                    if (match && 
outerVariables.get("$expr3").getLeaf().toString().equals(variableName)) {
+                        varNames.put(innerVariables.get("$meth1"), 
innerVariables.get("$var1"));
+                        convertPath.add(getCurrentPath());
+                    }
+                    return super.visitVariable(node, p);
+                }
+
+                @Override
+                protected boolean isCanceled() {
+                    return ctx.isCanceled();
+                }
+            }.scan(ctx.getPath(), null);
+            TypeElement type = (TypeElement) 
ctx.getInfo().getTrees().getElement(ctx.getVariables().get("$typeI0"));
+            List<? extends RecordComponentElement> recordSig = 
type.getRecordComponents();
+            if (!convertPath.isEmpty()) {
+                Fix fix = new FixImpl(ctx.getInfo(), ctx.getPath(), 
convertPath, recordSig, varNames, localVarList).toEditorFix();
+                return ErrorDescriptionFactory.forName(ctx, ctx.getPath(), 
Bundle.ERR_ConvertToRecordPattern(), fix);
+            }
+        }
+        return null;
+    }
+
+    private static final class FixImpl extends JavaFix {
+
+        private final Set<TreePathHandle> replaceOccurrences;
+        private final List<? extends ElementHandle> recordSig;
+        private final Map<String, String> varNames;
+        private final Set<String> localVarList;
+
+        public FixImpl(CompilationInfo info, TreePath main, Set<TreePath> 
replaceOccurrences, List<? extends RecordComponentElement> recordSig, 
Map<String, String> varNames, Set<String> localVarList) {
+            super(info, main);
+            this.recordSig = recordSig.stream().map(elem -> 
ElementHandle.create(elem)).collect(Collectors.toList());
+            this.varNames = varNames;
+            this.replaceOccurrences = replaceOccurrences.stream().map(tp -> 
TreePathHandle.create(tp, info)).collect(Collectors.toSet());
+            this.localVarList = new HashSet<>(localVarList);
+        }
+
+        @Override
+        protected String getText() {
+            return Bundle.FIX_ConvertToRecordPattern();
+        }
+
+        @Override
+        protected void performRewrite(JavaFix.TransformationContext ctx) {
+            WorkingCopy wc = ctx.getWorkingCopy();
+            TreePath main = ctx.getPath();
+            IfTree it = (IfTree) main.getLeaf();
+            InstanceOfTree iot = (InstanceOfTree) ((ParenthesizedTree) 
it.getCondition()).getExpression();
+            BindingPatternTree pattern = (BindingPatternTree) iot.getPattern();
+            StatementTree bt = it.getThenStatement();
+
+            List<PatternTree> bindTree = new ArrayList<>();
+
+            List<RecordComponentElement> recordSignature = new ArrayList<>();
+            recordSig.stream().map(elem -> elem.resolve(wc)).forEach(elem -> {
+                recordSignature.add((RecordComponentElement) elem);
+            });
+            Set<String> localVars = new HashSet<>(localVarList);
+            for (RecordComponentElement recordComponent : recordSignature) {
+                String compName = recordComponent.getSimpleName().toString();
+                String name = null;
+                String returnType = null;
+                if (varNames.containsKey(compName)) {
+                    name = varNames.get(compName);
+                } else {
+                    int cnt = 1;
+                    name = compName;
+                    while (SourceVersion.isKeyword(name) || 
localVars.contains(name)) {
+                        name = CodeStyleUtils.addPrefixSuffix(compName + 
cnt++, "", "");
+                    }
+                    localVars.add(name);
+                }
+
+                returnType = 
recordComponent.getAccessor().getReturnType().toString();
+                returnType = returnType.substring(returnType.lastIndexOf(".") 
+ 1);
+                bindTree.add((BindingPatternTree) 
wc.getTreeMaker().BindingPattern(wc.getTreeMaker().Variable(wc.getTreeMaker().
+                        Modifiers(EnumSet.noneOf(Modifier.class)), name, 
wc.getTreeMaker().Identifier(returnType), null)));
+            }
+            InstanceOfTree cond = 
wc.getTreeMaker().InstanceOf(iot.getExpression(), 
wc.getTreeMaker().RecordPattern((ExpressionTree) pattern.
+                    getVariable().getType(), bindTree, pattern.getVariable()));
+            List<Tree> removeList = replaceOccurrences.stream().map(tph -> 
tph.resolve(wc).getLeaf()).collect(Collectors.toList());
+            for (Tree t : removeList) {
+                bt = wc.getTreeMaker().removeBlockStatement((BlockTree) bt, 
(StatementTree) t);
+            }
+            wc.rewrite(it, 
wc.getTreeMaker().If(wc.getTreeMaker().Parenthesized(cond), bt, 
it.getElseStatement()));
+        }
+    }
+}
diff --git 
a/java/java.hints/test/unit/src/org/netbeans/modules/java/hints/jdk/ConvertToNestedRecordPatternTest.java
 
b/java/java.hints/test/unit/src/org/netbeans/modules/java/hints/jdk/ConvertToNestedRecordPatternTest.java
new file mode 100644
index 0000000000..d985c5929f
--- /dev/null
+++ 
b/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"
+                        + "            Point p = ul.p();\n"
+                        + "            System.out.println(\"Hello\");\n"
+                        + "        }\n"
+                        + "    }\n"
+                        + "}\n")
+                .sourceLevel(SourceVersion.latest().name())
+                .options("--enable-preview")
+                .run(ConvertToNestedRecordPattern.class)
+                .findWarning("7:25-7:63:verifier:" + 
Bundle.ERR_ConvertToNestedRecordPattern())
+                .applyFix()
+                .assertCompilable()
+                .assertOutput("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(Point p, 
Color c) ul, ColoredPoint(Point p1, Color c1) lr)) {\n"
+                        + "            System.out.println(\"Hello\");\n"
+                        + "        }\n"
+                        + "    }\n"
+                        + "}\n");
+    }
+
+    public void testMultipleNested() throws Exception {
+        if (!isRecordClassPresent()) {
+            return;
+        }
+        HintTest.create()
+                .input("package test;\n"
+                        + "record Rect(ColoredPoint upperLeft) {}\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(Point p, 
Color c) ul)) {\n"
+                        + "            int x = p.x();\n"
+                        + "            System.out.println(\"Hello\");\n"
+                        + "        }\n"
+                        + "    }\n"
+                        + "}\n")
+                .sourceLevel(SourceVersion.latest().name())
+                .options("--enable-preview")
+                .run(ConvertToNestedRecordPattern.class)
+                .findWarning("7:25-7:64:verifier:" + 
Bundle.ERR_ConvertToNestedRecordPattern())
+                .applyFix()
+                .assertCompilable()
+                .assertOutput("package test;\n"
+                        + "record Rect(ColoredPoint upperLeft) {}\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(Point(int x, int y) p, Color c) ul)) {\n"
+                        + "            System.out.println(\"Hello\");\n"
+                        + "        }\n"
+                        + "    }\n"
+                        + "}\n");
+    }
+
+    public void testUserVar() throws Exception {
+        if (!isRecordClassPresent()) {
+            return;
+        }
+        HintTest.create()
+                .input("package test;\n"
+                        + "record Rect(ColoredPoint upperLeft,ColoredPoint 
lr,ColoredPoint ur) {}\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(Point p, 
Color c) ul, ColoredPoint lr, ColoredPoint(Point p1, Color c1) ur)) {\n"
+                        + "            int xVal = p.x();\n"
+                        + "            int y1 = p.y();\n"
+                        + "            Point p2 = lr.p();\n"
+                        + "            System.out.println(\"Hello\");\n"
+                        + "        }\n"
+                        + "    }\n"
+                        + "}\n")
+                .sourceLevel(SourceVersion.latest().name())
+                .options("--enable-preview")
+                .run(ConvertToNestedRecordPattern.class)
+                .findWarning("7:25-7:118:verifier:" + 
Bundle.ERR_ConvertToNestedRecordPattern())
+                .applyFix()
+                .assertCompilable()
+                .assertOutput("package test;\n"
+                        + "record Rect(ColoredPoint upperLeft,ColoredPoint 
lr,ColoredPoint ur) {}\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(Point(int xVal, int y1) p, Color c) ul, ColoredPoint(Point 
p2, Color c2) lr, ColoredPoint(Point(int x, int y) p1, Color c1) ur)) {\n"
+                        + "            System.out.println(\"Hello\");\n"
+                        + "        }\n"
+                        + "    }\n"
+                        + "}\n");
+    }
+
+    private boolean isRecordClassPresent() {
+        try {
+            Class.forName("java.lang.Record");
+            return true;
+        } catch (ClassNotFoundException ex) {
+            return false;
+        }
+    }
+}
diff --git 
a/java/java.hints/test/unit/src/org/netbeans/modules/java/hints/jdk/ConvertToRecordPatternTest.java
 
b/java/java.hints/test/unit/src/org/netbeans/modules/java/hints/jdk/ConvertToRecordPatternTest.java
new file mode 100644
index 0000000000..72cd50c080
--- /dev/null
+++ 
b/java/java.hints/test/unit/src/org/netbeans/modules/java/hints/jdk/ConvertToRecordPatternTest.java
@@ -0,0 +1,145 @@
+/*
+ * 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 ConvertToRecordPatternTest extends NbTestCase {
+
+    public ConvertToRecordPatternTest(String name) {
+        super(name);
+    }
+
+    public void testSimple() throws Exception {
+        if (!isRecordClassPresent()) {
+            return;
+        }
+        HintTest.create()
+                .input("package test;\n"
+                        + "record Person(String name, String place){}\n"
+                        + "public class Test {\n"
+                        + "    private int test(Object o) {\n"
+                        + "        if (o instanceof Person p) {\n"
+                        + "            String name = p.name();\n"
+                        + "            return name.length();\n"
+                        + "        }\n"
+                        + "        return -1;\n"
+                        + "    }\n"
+                        + "}\n")
+                .sourceLevel(SourceVersion.latest().name())
+                .options("--enable-preview")
+                .run(ConvertToRecordPattern.class)
+                .findWarning("4:8-4:10:verifier:" + 
Bundle.ERR_ConvertToRecordPattern())
+                .applyFix()
+                .assertCompilable()
+                .assertOutput("package test;\n"
+                        + "record Person(String name, String place){}\n"
+                        + "public class Test {\n"
+                        + "    private int test(Object o) {\n"
+                        + "        if (o instanceof Person(String name, String 
place) p) {\n"
+                        + "            return name.length();\n"
+                        + "        }\n"
+                        + "        return -1;\n"
+                        + "    }\n"
+                        + "}\n");
+    }
+
+    public void testDuplicateVarName() throws Exception {
+        if (!isRecordClassPresent()) {
+            return;
+        }
+        HintTest.create()
+                .input("package test;\n"
+                        + "record Person(String name, int s){}\n"
+                        + "public class Test {\n"
+                        + "    private int test(Object s) {\n"
+                        + "        if (s instanceof Person p) {\n"
+                        + "            String name = p.name();\n"
+                        + "            return name.length();\n"
+                        + "        }\n"
+                        + "        return -1;\n"
+                        + "    }\n"
+                        + "}\n")
+                .sourceLevel(SourceVersion.latest().name())
+                .options("--enable-preview")
+                .run(ConvertToRecordPattern.class)
+                .findWarning("4:8-4:10:verifier:" + 
Bundle.ERR_ConvertToRecordPattern())
+                .applyFix()
+                .assertCompilable()
+                .assertOutput("package test;\n"
+                        + "record Person(String name, int s){}\n"
+                        + "public class Test {\n"
+                        + "    private int test(Object s) {\n"
+                        + "        if (s instanceof Person(String name, int 
s1) p) {\n"
+                        + "            return name.length();\n"
+                        + "        }\n"
+                        + "        return -1;\n"
+                        + "    }\n"
+                        + "}\n");
+    }
+
+    public void testUsingUserVar() throws Exception {
+        if (!isRecordClassPresent()) {
+            return;
+        }
+        HintTest.create()
+                .input("package test;\n"
+                        + "record Person(String name, int s){}\n"
+                        + "public class Test {\n"
+                        + "    private int test(Object s) {\n"
+                        + "        if (s instanceof Person p) {\n"
+                        + "            String userName = p.name();\n"
+                        + "            return userName.length();\n"
+                        + "        }\n"
+                        + "        return -1;\n"
+                        + "    }\n"
+                        + "}\n")
+                .sourceLevel(SourceVersion.latest().name())
+                .options("--enable-preview")
+                .run(ConvertToRecordPattern.class)
+                .findWarning("4:8-4:10:verifier:" + 
Bundle.ERR_ConvertToRecordPattern())
+                .applyFix()
+                .assertCompilable()
+                .assertOutput("package test;\n"
+                        + "record Person(String name, int s){}\n"
+                        + "public class Test {\n"
+                        + "    private int test(Object s) {\n"
+                        + "        if (s instanceof Person(String userName, 
int s1) p) {\n"
+                        + "            return userName.length();\n"
+                        + "        }\n"
+                        + "        return -1;\n"
+                        + "    }\n"
+                        + "}\n");
+    }
+
+    private boolean isRecordClassPresent() {
+        try {
+            Class.forName("java.lang.Record");
+            return true;
+        } catch (ClassNotFoundException ex) {
+            return false;
+        }
+    }
+}
diff --git 
a/java/java.source.base/src/org/netbeans/api/java/source/TreeMaker.java 
b/java/java.source.base/src/org/netbeans/api/java/source/TreeMaker.java
index cb830c6249..ac708a8fe8 100644
--- a/java/java.source.base/src/org/netbeans/api/java/source/TreeMaker.java
+++ b/java/java.source.base/src/org/netbeans/api/java/source/TreeMaker.java
@@ -1278,6 +1278,19 @@ public final class TreeMaker {
         return delegate.BindingPattern(vt);
     }
 
+      /**
+     * Creates a new Tree for a given DeconstructionPatternTree
+     * @param deconstructor deconstructor of record pattern
+     * @param nested list of nested patterns
+     * @param vt the variable of record pattern
+     * @see com.sun.source.tree.DeconstructionPatternTree
+     * @return the newly created RecordPatternTree
+     * @since 19
+     */
+    public DeconstructionPatternTree RecordPattern(ExpressionTree 
deconstructor, List<PatternTree> nested, VariableTree vt) {
+        return delegate.DeconstructionPattern(deconstructor, nested, vt);
+    }
+
     /**
      * Creates a new VariableTree from a VariableElement.
      *
diff --git 
a/java/java.source.base/src/org/netbeans/modules/java/source/TreeShims.java 
b/java/java.source.base/src/org/netbeans/modules/java/source/TreeShims.java
index 46389a0a19..1702191252 100644
--- a/java/java.source.base/src/org/netbeans/modules/java/source/TreeShims.java
+++ b/java/java.source.base/src/org/netbeans/modules/java/source/TreeShims.java
@@ -60,6 +60,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";
+//    public static final String RECORDPATTERN = "RECORDPATTERN";
 //
 //    public static List<? extends ExpressionTree> getExpressions(CaseTree 
node) {
 //        try {
@@ -390,6 +392,58 @@ public class TreeShims {
 //        } catch (IllegalAccessException | IllegalArgumentException | 
InvocationTargetException ex) {
 //            throw TreeShims.<RuntimeException>throwAny(ex);
 //        }
+//    }
+
+//  public static ExpressionTree getDeconstructor(Tree node) {
+//        try {
+//            Class gpt = 
Class.forName("com.sun.source.tree.DeconstructionPatternTree"); //NOI18N
+//            return isJDKVersionRelease19_Or_Above()
+//                    ? (ExpressionTree) 
gpt.getDeclaredMethod("getDeconstructor").invoke(node) //NOI18N
+//                    : null;
+//        } catch (NoSuchMethodException | ClassNotFoundException ex) {
+//            return null;
+//        } catch (IllegalAccessException | IllegalArgumentException | 
InvocationTargetException ex) {
+//            throw TreeShims.<RuntimeException>throwAny(ex);
+//        }
+//    }
+
+//    public static List<? extends PatternTree> getNestedPatterns(Tree node) {
+//        try {
+//            Class gpt = 
Class.forName("com.sun.source.tree.DeconstructionPatternTree"); //NOI18N
+//            return isJDKVersionRelease19_Or_Above()
+//                    ? (List<? extends PatternTree>) 
gpt.getDeclaredMethod("getNestedPatterns").invoke(node) //NOI18N
+//                    : null;
+//        } catch (NoSuchMethodException | ClassNotFoundException ex) {
+//            return null;
+//        } catch (IllegalAccessException | IllegalArgumentException | 
InvocationTargetException ex) {
+//            throw TreeShims.<RuntimeException>throwAny(ex);
+//        }
+//    }
+
+//    public static VariableTree getVariable(Tree node) {
+//        try {
+//            Class gpt = 
Class.forName("com.sun.source.tree.DeconstructionPatternTree"); //NOI18N
+//            return isJDKVersionRelease19_Or_Above()
+//                    ? (VariableTree) 
gpt.getDeclaredMethod("getVariable").invoke(node) //NOI18N
+//                    : null;
+//        } catch (NoSuchMethodException | ClassNotFoundException ex) {
+//            return null;
+//        } catch (IllegalAccessException | IllegalArgumentException | 
InvocationTargetException ex) {
+//            throw TreeShims.<RuntimeException>throwAny(ex);
+//        }
+//    }
+
+//    public static Tree RecordPattern(TreeMaker make, ExpressionTree 
deconstructor, List<PatternTree> nested, VariableTree var) {
+//        ListBuffer<JCTree.JCPattern> nestedVar = new ListBuffer<>();
+//        for (PatternTree t : nested) {
+//            nestedVar.append((JCTree.JCPattern) t);
+//        }
+//        try {
+//            Method getMethod = 
TreeMaker.class.getDeclaredMethod("RecordPattern", JCTree.JCExpression.class, 
com.sun.tools.javac.util.List.class, JCTree.JCVariableDecl.class);
+//            return (Tree) getMethod.invoke(make, (JCTree.JCExpression) 
deconstructor, nestedVar.toList(), (JCTree.JCVariableDecl) var);
+//        } catch (NoSuchMethodException | IllegalAccessException | 
IllegalArgumentException | InvocationTargetException ex) {
+//            throw TreeShims.<RuntimeException>throwAny(ex);
+//        }
 //    }
 
     public static Element toRecordComponent(Element el) {
@@ -425,6 +479,10 @@ public class TreeShims {
         return 
Integer.valueOf(SourceVersion.latest().name().split("_")[1]).compareTo(17) >= 0;
     }
 
+//    public static boolean isJDKVersionRelease19_Or_Above(){
+//        return 
Integer.valueOf(SourceVersion.latest().name().split("_")[1]).compareTo(19) >= 0;
+//    }
+
 //    public static boolean isJDKVersionRelease18_Or_Above() {
 //        return 
Integer.valueOf(SourceVersion.latest().name().split("_")[1]).compareTo(18) >= 0;
 //    }
diff --git 
a/java/java.source.base/src/org/netbeans/modules/java/source/pretty/VeryPretty.java
 
b/java/java.source.base/src/org/netbeans/modules/java/source/pretty/VeryPretty.java
index 5a76b60586..efb1458744 100644
--- 
a/java/java.source.base/src/org/netbeans/modules/java/source/pretty/VeryPretty.java
+++ 
b/java/java.source.base/src/org/netbeans/modules/java/source/pretty/VeryPretty.java
@@ -26,6 +26,7 @@ import com.sun.source.tree.LambdaExpressionTree.BodyKind;
 import com.sun.source.tree.MemberReferenceTree.ReferenceMode;
 import com.sun.source.tree.MethodTree;
 import com.sun.source.tree.ModuleTree;
+import com.sun.source.tree.PatternTree;
 import com.sun.source.tree.StatementTree;
 import com.sun.source.tree.Tree;
 import static com.sun.source.tree.Tree.*;
@@ -2091,8 +2092,26 @@ public final class VeryPretty extends JCTree.Visitor 
implements DocTreeVisitor<V
 
     @Override
     public void visitTree(JCTree tree) {
-       print("(UNKNOWN: " + tree + ")");
-       newline();
+        print("(UNKNOWN: " + tree + ")");
+        newline();
+    }
+    
+    @Override
+    public void visitRecordPattern(JCRecordPattern tree) {
+        print(tree.deconstructor);
+        print("(");
+        Iterator<JCPattern> it = tree.nested.iterator();
+        while (it.hasNext()) {
+            JCPattern pattern = it.next();
+            doAccept(pattern, true);
+            if (it.hasNext()) {
+                print(", ");
+            }
+        }
+        print(") ");
+        if (tree.var != null) {
+            print(tree.var.name.toString());
+        }
     }
 
     /**************************************************************************
diff --git 
a/java/java.source.base/src/org/netbeans/modules/java/source/save/CasualDiff.java
 
b/java/java.source.base/src/org/netbeans/modules/java/source/save/CasualDiff.java
index 3bc2d5dd28..f13b66e1ac 100644
--- 
a/java/java.source.base/src/org/netbeans/modules/java/source/save/CasualDiff.java
+++ 
b/java/java.source.base/src/org/netbeans/modules/java/source/save/CasualDiff.java
@@ -105,6 +105,7 @@ import com.sun.tools.javac.tree.JCTree.JCPackageDecl;
 import com.sun.tools.javac.tree.JCTree.JCParens;
 import com.sun.tools.javac.tree.JCTree.JCPrimitiveTypeTree;
 import com.sun.tools.javac.tree.JCTree.JCProvides;
+import com.sun.tools.javac.tree.JCTree.JCRecordPattern;
 import com.sun.tools.javac.tree.JCTree.JCRequires;
 import com.sun.tools.javac.tree.JCTree.JCReturn;
 import com.sun.tools.javac.tree.JCTree.JCStatement;
@@ -1966,6 +1967,28 @@ public class CasualDiff {
         return diffTree((JCTree) oldT.var, (JCTree) newT.var, bounds);
     }
 
+    protected int diffRecordPattern(JCRecordPattern oldT, JCRecordPattern 
newT, int[] bounds) {
+        int localPointer = bounds[0];
+
+        // deconstructor
+        int[] exprBounds = getBounds(oldT.deconstructor);
+        copyTo(localPointer, exprBounds[0]);
+        localPointer = diffTree(oldT.deconstructor, newT.deconstructor, 
exprBounds);
+
+        // Nested Patterns
+        Iterator<? extends JCTree> oldTIter = oldT.nested.iterator();
+        Iterator<? extends JCTree> newTIter = newT.nested.iterator();
+        while (oldTIter.hasNext()) {
+            JCTree oldP = oldTIter.next();
+            JCTree newP = newTIter.next();
+            int[] patternBounds = getBounds(oldP);
+            copyTo(localPointer, patternBounds[0]);
+            localPointer = diffTree(oldP, newP, patternBounds);
+        }
+        copyTo(localPointer, bounds[1]);
+        return bounds[1];
+    }
+
     protected int diffConstantCaseLabel(JCConstantCaseLabel oldT, 
JCConstantCaseLabel newT, int[] bounds) {
         return diffTree((JCTree) oldT.expr, (JCTree) newT.expr, bounds);
     }
@@ -5720,6 +5743,9 @@ public class CasualDiff {
           case CONSTANTCASELABEL:
               retVal = diffConstantCaseLabel((JCConstantCaseLabel) oldT, 
(JCConstantCaseLabel) newT, elementBounds);
               break;
+          case RECORDPATTERN:
+              retVal = diffRecordPattern((JCRecordPattern) oldT, 
(JCRecordPattern) newT, elementBounds);
+              break;
           default:
               // handle special cases like field groups and enum constants
               if (oldT.getKind() == Kind.OTHER) {
diff --git 
a/java/java.source.base/src/org/netbeans/modules/java/source/save/Reformatter.java
 
b/java/java.source.base/src/org/netbeans/modules/java/source/save/Reformatter.java
index 941da1c039..e04f054f03 100644
--- 
a/java/java.source.base/src/org/netbeans/modules/java/source/save/Reformatter.java
+++ 
b/java/java.source.base/src/org/netbeans/modules/java/source/save/Reformatter.java
@@ -2825,8 +2825,10 @@ public class Reformatter implements ReformatTask {
         @Override
         public Boolean visitDeconstructionPattern(DeconstructionPatternTree 
node, Void p) {
             scan(node.getDeconstructor(), p);
+            spaces(0);
             accept(LPAREN);
-            scan(node.getNestedPatterns(), p);
+            spaces(cs.spaceWithinMethodDeclParens() ? 1 : 0, true);
+            wrapList(cs.wrapMethodParams(), cs.alignMultilineMethodParams(), 
false, COMMA, node.getNestedPatterns());
             accept(RPAREN);
             if (node.getVariable() != null) {
                 space();
diff --git 
a/java/java.source.base/test/unit/src/org/netbeans/modules/java/source/save/FormatingTest.java
 
b/java/java.source.base/test/unit/src/org/netbeans/modules/java/source/save/FormatingTest.java
index a7b245a078..c4afa398dd 100644
--- 
a/java/java.source.base/test/unit/src/org/netbeans/modules/java/source/save/FormatingTest.java
+++ 
b/java/java.source.base/test/unit/src/org/netbeans/modules/java/source/save/FormatingTest.java
@@ -3322,6 +3322,183 @@ public class FormatingTest extends NbTestCase {
         reformat(doc, content, golden);
     }
 
+    public void testNormalRecordPattern() throws Exception {
+        try {
+            SourceVersion.valueOf("RELEASE_19"); //NOI18N
+        } catch (IllegalArgumentException ex) {
+            return;
+        }
+        testFile = new File(getWorkDir(), "Test.java");
+        TestUtilities.copyStringToFile(testFile, "");
+        FileObject testSourceFO = FileUtil.toFileObject(testFile);
+        DataObject testSourceDO = DataObject.find(testSourceFO);
+        EditorCookie ec = (EditorCookie) 
testSourceDO.getCookie(EditorCookie.class);
+        final Document doc = ec.openDocument();
+        doc.putProperty(Language.class, JavaTokenId.language());
+        String content = "package test;\n"
+                + "record Point(int x, int y){}\n"
+                + "public class Test {\n"
+                + "    private void test(Object o) {\n"
+                + "        if (o instanceof Point\n"
+                + "                (int     x, int    \n"
+                + "                y) p) {\n"
+                + "            System.out.println(\"Hello\");\n"
+                + "        }\n"
+                + "    }\n"
+                + "}";
+
+        String golden = "package test;\n"
+                + "\n"
+                + "record Point(int x, int y) {\n"
+                + "\n"
+                + "}\n"
+                + "\n"
+                + "public class Test {\n"
+                + "\n"
+                + "    private void test(Object o) {\n"
+                + "        if (o instanceof Point(int x, int y) p) {\n"
+                + "            System.out.println(\"Hello\");\n"
+                + "        }\n"
+                + "    }\n"
+                + "}"
+                + "\n";
+        reformat(doc, content, golden);
+    }
+
+    public void testNestedRecordPattern() throws Exception {
+        try {
+            SourceVersion.valueOf("RELEASE_19"); //NOI18N
+        } catch (IllegalArgumentException ex) {
+            //OK, no RELEASE_19, skip test
+            return;
+        }
+        testFile = new File(getWorkDir(), "Test.java");
+        TestUtilities.copyStringToFile(testFile, "");
+        FileObject testSourceFO = FileUtil.toFileObject(testFile);
+        DataObject testSourceDO = DataObject.find(testSourceFO);
+        EditorCookie ec = (EditorCookie) 
testSourceDO.getCookie(EditorCookie.class);
+        final Document doc = ec.openDocument();
+        doc.putProperty(Language.class, JavaTokenId.language());
+        String content = "package test;\n"
+                + "\n"
+                + "record Rect(ColoredPoint ul,ColoredPoint lr) {}\n"
+                + "enum Color {RED,GREEN,BLUE}\n"
+                + "record ColoredPoint(Point p, Color c) {}\n"
+                + "record Point(int x, int y) {}\n"
+                + "\n"
+                + "public class Test {\n"
+                + "\n"
+                + "    private void test(Object o) {\n"
+                + "        if (o instanceof\n"
+                + "                Rect\n"
+                + "                (       ColoredPoint      ul,   
ColoredPoint\n"
+                + "                        lr)    r) {\n"
+                + "            Point p = ul.p();\n"
+                + "            System.out.println(\"Hello\");\n"
+                + "        }\n"
+                + "    }\n"
+                + "}";
+
+        String golden = "package test;\n"
+                + "\n"
+                + "record Rect(ColoredPoint ul, ColoredPoint lr) {\n"
+                + "\n"
+                + "}\n"
+                + "\n"
+                + "enum Color {\n"
+                + "    RED, GREEN, BLUE\n"
+                + "}\n"
+                + "\n"
+                + "record ColoredPoint(Point p, Color c) {\n"
+                + "\n"
+                + "}\n"
+                + "\n"
+                + "record Point(int x, int y) {\n"
+                + "\n"
+                + "}\n"
+                + "\n"
+                + "public class Test {\n"
+                + "\n"
+                + "    private void test(Object o) {\n"
+                + "        if (o instanceof Rect(ColoredPoint ul, ColoredPoint 
lr) r) {\n"
+                + "            Point p = ul.p();\n"
+                + "            System.out.println(\"Hello\");\n"
+                + "        }\n"
+                + "    }\n"
+                + "}"
+                + "\n";
+        reformat(doc, content, golden);
+    }
+
+    public void testMultipleNestingRecordPattern() throws Exception {
+        try {
+            SourceVersion.valueOf("RELEASE_19"); //NOI18N
+        } catch (IllegalArgumentException ex) {
+            //OK, no RELEASE_19, skip test
+            return;
+        }
+        testFile = new File(getWorkDir(), "Test.java");
+        TestUtilities.copyStringToFile(testFile, "");
+        FileObject testSourceFO = FileUtil.toFileObject(testFile);
+        DataObject testSourceDO = DataObject.find(testSourceFO);
+        EditorCookie ec = (EditorCookie) 
testSourceDO.getCookie(EditorCookie.class);
+        final Document doc = ec.openDocument();
+        doc.putProperty(Language.class, JavaTokenId.language());
+        String content = "package test;\n"
+                + "\n"
+                + "record Rect(ColoredPoint ul,ColoredPoint lr) {}\n"
+                + "enum Color {RED,GREEN,BLUE}\n"
+                + "record ColoredPoint(Point p, Color c) {}\n"
+                + "record Point(int x, int y) {}\n"
+                + "\n"
+                + "public class Test {\n"
+                + "\n"
+                + "    private void test(Object o) {\n"
+                + "        if (o instanceof\n"
+                + "                Rect\n"
+                + "                (       ColoredPoint(Point   \n"
+                + "                        p, Color \n"
+                + "                                c\n"
+                + "                        )      ul,   ColoredPoint\n"
+                + "                        lr)    r\n"
+                + "                ) {\n"
+                + "            int x = p.x();\n"
+                + "            System.out.println(\"Hello\");\n"
+                + "        }\n"
+                + "    }\n"
+                + "}";
+
+        String golden = "package test;\n"
+                + "\n"
+                + "record Rect(ColoredPoint ul, ColoredPoint lr) {\n"
+                + "\n"
+                + "}\n"
+                + "\n"
+                + "enum Color {\n"
+                + "    RED, GREEN, BLUE\n"
+                + "}\n"
+                + "\n"
+                + "record ColoredPoint(Point p, Color c) {\n"
+                + "\n"
+                + "}\n"
+                + "\n"
+                + "record Point(int x, int y) {\n"
+                + "\n"
+                + "}\n"
+                + "\n"
+                + "public class Test {\n"
+                + "\n"
+                + "    private void test(Object o) {\n"
+                + "        if (o instanceof Rect(ColoredPoint(Point p, Color 
c) ul, ColoredPoint lr) r) {\n"
+                + "            int x = p.x();\n"
+                + "            System.out.println(\"Hello\");\n"
+                + "        }\n"
+                + "    }\n"
+                + "}"
+                + "\n";
+        reformat(doc, content, golden);
+    }
+    
     public void testDoWhile() throws Exception {
         testFile = new File(getWorkDir(), "Test.java");
         TestUtilities.copyStringToFile(testFile,


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscr...@netbeans.apache.org
For additional commands, e-mail: commits-h...@netbeans.apache.org

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

Reply via email to