diff --git a/RegExpSupport/src/org/intellij/lang/regexp/RegExpCompletionContributor.java b/RegExpSupport/src/org/intellij/lang/regexp/RegExpCompletionContributor.java index dc81e12c3030..974258537298 100644 --- a/RegExpSupport/src/org/intellij/lang/regexp/RegExpCompletionContributor.java +++ b/RegExpSupport/src/org/intellij/lang/regexp/RegExpCompletionContributor.java @@ -97,6 +97,12 @@ public final class RegExpCompletionContributor extends CompletionContributor { final ElementPattern propertyNamePattern = psiElement().afterLeaf(psiElement().withText("{").afterLeaf(propertyPattern)); extend(CompletionType.BASIC, propertyNamePattern, new PropertyNameCompletionProvider()); + + final PsiElementPattern.Capture namedCharacterPattern = psiElement().withText("N"); + extend(CompletionType.BASIC, psiElement().afterLeaf(namedCharacterPattern), + new NamedCharacterCompletionProvider(true)); + extend(CompletionType.BASIC, psiElement().afterLeaf(psiElement(RegExpTT.LBRACE).afterLeaf(namedCharacterPattern)), + new NamedCharacterCompletionProvider(false)); } } diff --git a/RegExpSupport/src/org/intellij/lang/regexp/UnicodeCharacterNames.java b/RegExpSupport/src/org/intellij/lang/regexp/UnicodeCharacterNames.java index 57a465111d16..a84105ec40df 100644 --- a/RegExpSupport/src/org/intellij/lang/regexp/UnicodeCharacterNames.java +++ b/RegExpSupport/src/org/intellij/lang/regexp/UnicodeCharacterNames.java @@ -33,14 +33,16 @@ public class UnicodeCharacterNames { try { final Class aClass = Class.forName("java.lang.CharacterName"); final Method initNamePool = ReflectionUtil.getDeclaredMethod(aClass, "initNamePool"); - final int[][] lookup2d = ReflectionUtil.getField(aClass, null, int[][].class, "lookup"); - if (initNamePool != null && lookup2d != null) { // jdk 8 - byte[] namePool = (byte[])initNamePool.invoke(null); + if (initNamePool != null) { // jdk 8 + byte[] namePool = (byte[])initNamePool.invoke(null); // initializes "lookup" field + final int[][] lookup2d = ReflectionUtil.getStaticFieldValue(aClass, int[][].class, "lookup"); + if (lookup2d == null) { + return; + } for (int[] indexes : lookup2d) { if (indexes != null) { for (int index : indexes) { if (index != 0) { - ; final String name = new String(namePool, index >>> 8, index & 0xff, AsciiUtil.ASCII_CHARSET); consumer.accept(name); } diff --git a/RegExpSupport/test/org/intellij/lang/regexp/RegExpCompletionTest.java b/RegExpSupport/test/org/intellij/lang/regexp/RegExpCompletionTest.java index 3ba88ab02baa..abdee64fbc05 100644 --- a/RegExpSupport/test/org/intellij/lang/regexp/RegExpCompletionTest.java +++ b/RegExpSupport/test/org/intellij/lang/regexp/RegExpCompletionTest.java @@ -15,9 +15,11 @@ */ package org.intellij.lang.regexp; +import com.intellij.codeInsight.lookup.LookupElement; import com.intellij.openapi.application.PathManager; import com.intellij.testFramework.fixtures.CodeInsightFixtureTestCase; import com.intellij.util.ArrayUtil; +import com.intellij.util.containers.ContainerUtil; import java.io.File; import java.util.ArrayList; @@ -57,6 +59,17 @@ public class RegExpCompletionTest extends CodeInsightFixtureTestCase { myFixture.checkResult("[[:^alpha:]"); } + public void testNamedCharacter() { + myFixture.configureByText(RegExpFileType.INSTANCE, "\\\\N{SMILE}"); + final LookupElement[] elements = myFixture.completeBasic(); + final List strings = ContainerUtil.map(elements, LookupElement::getLookupString); + assertEquals(Arrays.asList("SMILE", "SMILING FACE WITH SMILING EYES", "SMILING FACE WITH HEART-SHAPED EYES", + "SMILING CAT FACE WITH HEART-SHAPED EYES", "SMILING FACE WITH OPEN MOUTH AND SMILING EYES", + "SMILING FACE WITH OPEN MOUTH AND TIGHTLY-CLOSED EYES", "CAT FACE WITH WRY SMILE", + "GRINNING CAT FACE WITH SMILING EYES", "GRINNING FACE WITH SMILING EYES", + "KISSING FACE WITH SMILING EYES"), strings); + } + public void testBackSlashVariants() throws Throwable { List nameList = new ArrayList<>(Arrays.asList("d", "D", "s", "S", "w", "W", "b", "B", "A", "G", "Z", "z", "Q", "E",