From 4635ede0a0d144365a8a239611cd337f0b444835 Mon Sep 17 00:00:00 2001 From: Bas Leijdekkers Date: Mon, 10 Jun 2019 11:58:58 +0200 Subject: [PATCH] member fragments for java GitOrigin-RevId: 462f1aea94204baf0dd7a579b4826adf82d712a6 --- .../psi/impl/JavaCodeFragmentFactoryImpl.java | 21 ++++---------- .../intellij/psi/JavaCodeFragmentFactory.java | 28 +++++++++---------- .../psi/impl/source/tree/JavaElementType.java | 13 ++++++++- .../JavaStructuralSearchProfile.java | 20 ++++++++++++- .../util/resources/misc/registry.properties | 2 ++ 5 files changed, 52 insertions(+), 32 deletions(-) diff --git a/java/java-impl/src/com/intellij/psi/impl/JavaCodeFragmentFactoryImpl.java b/java/java-impl/src/com/intellij/psi/impl/JavaCodeFragmentFactoryImpl.java index f0623c07049f..89554df23fcd 100644 --- a/java/java-impl/src/com/intellij/psi/impl/JavaCodeFragmentFactoryImpl.java +++ b/java/java-impl/src/com/intellij/psi/impl/JavaCodeFragmentFactoryImpl.java @@ -1,18 +1,4 @@ -/* - * Copyright 2000-2011 JetBrains s.r.o. - * - * Licensed 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. - */ +// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. package com.intellij.psi.impl; import com.intellij.openapi.project.Project; @@ -67,4 +53,9 @@ public class JavaCodeFragmentFactoryImpl extends JavaCodeFragmentFactory { final boolean isClassesAccepted) { return new PsiJavaCodeReferenceCodeFragmentImpl(myProject, isPhysical, "fragment.java", text, isClassesAccepted, context); } + + @Override + public JavaCodeFragment createMemberCodeFragment(@NotNull String text, @Nullable PsiElement context, boolean isPhysical) { + return new PsiCodeFragmentImpl(myProject, JavaElementType.MEMBERS, isPhysical, "fragment.java", text, context); + } } diff --git a/java/java-psi-api/src/com/intellij/psi/JavaCodeFragmentFactory.java b/java/java-psi-api/src/com/intellij/psi/JavaCodeFragmentFactory.java index 9987d5589fe5..9589cf9c64e2 100644 --- a/java/java-psi-api/src/com/intellij/psi/JavaCodeFragmentFactory.java +++ b/java/java-psi-api/src/com/intellij/psi/JavaCodeFragmentFactory.java @@ -1,18 +1,4 @@ -/* - * Copyright 2000-2014 JetBrains s.r.o. - * - * Licensed 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. - */ +// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. package com.intellij.psi; import com.intellij.openapi.components.ServiceManager; @@ -122,4 +108,16 @@ public abstract class JavaCodeFragmentFactory { boolean isPhysical, boolean isClassesAccepted); + /** + * Creates a Java code fragment from the text of a Java class member (field, method, class initializer, nested class). + * + * @param text the text of the member to create + * @param context the context for resolving references from the member + * @param isPhysical whether the code fragment is created as a physical element + * (see {@link PsiElement#isPhysical()}). + * @return the created code fragment. + */ + public abstract JavaCodeFragment createMemberCodeFragment(@NotNull String text, + @Nullable PsiElement context, + boolean isPhysical); } diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/JavaElementType.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/JavaElementType.java index 472ea32d98f8..77aa89059622 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/JavaElementType.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/JavaElementType.java @@ -1,4 +1,4 @@ -// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. +// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. package com.intellij.psi.impl.source.tree; import com.intellij.lang.*; @@ -171,6 +171,17 @@ public interface JavaElementType { } ILazyParseableElementType CODE_BLOCK = new ICodeBlockElementType(); + IElementType MEMBERS = new ICodeFragmentElementType("MEMBERS", JavaLanguage.INSTANCE) { + private final JavaParserUtil.ParserWrapper myParser = + builder -> JavaParser.INSTANCE.getDeclarationParser().parseClassBodyDeclarations(builder, false); + + @Nullable + @Override + public ASTNode parseContents(@NotNull ASTNode chameleon) { + return JavaParserUtil.parseFragment(chameleon, myParser); + } + }; + IElementType STATEMENTS = new ICodeFragmentElementType("STATEMENTS", JavaLanguage.INSTANCE) { private final JavaParserUtil.ParserWrapper myParser = builder -> JavaParser.INSTANCE.getStatementParser().parseStatements(builder); diff --git a/java/structuralsearch-java/src/com/intellij/structuralsearch/JavaStructuralSearchProfile.java b/java/structuralsearch-java/src/com/intellij/structuralsearch/JavaStructuralSearchProfile.java index 0eadc89d1150..6a6ffb85d3fc 100644 --- a/java/structuralsearch-java/src/com/intellij/structuralsearch/JavaStructuralSearchProfile.java +++ b/java/structuralsearch-java/src/com/intellij/structuralsearch/JavaStructuralSearchProfile.java @@ -12,6 +12,7 @@ import com.intellij.lang.java.JavaLanguage; import com.intellij.openapi.fileTypes.LanguageFileType; import com.intellij.openapi.fileTypes.StdFileTypes; import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.registry.Registry; import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.*; import com.intellij.psi.impl.source.JavaDummyHolder; @@ -37,6 +38,7 @@ import com.intellij.structuralsearch.plugin.ui.UIUtil; import com.intellij.util.ArrayUtil; import com.intellij.util.IncorrectOperationException; import com.intellij.util.SmartList; +import com.intellij.util.containers.ContainerUtil; import gnu.trove.THashSet; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -50,6 +52,10 @@ import java.util.stream.Collectors; */ public class JavaStructuralSearchProfile extends StructuralSearchProfile { + public static final PatternContext DEFAULT_CONTEXT = new PatternContext("default", "Default"); + public static final PatternContext MEMBER_CONTEXT = new PatternContext("member", "Class Member"); + private static final List PATTERN_CONTEXTS = ContainerUtil.immutableList(DEFAULT_CONTEXT, MEMBER_CONTEXT); + private static final Set PRIMITIVE_TYPES = new THashSet<>(Arrays.asList( PsiKeyword.SHORT, PsiKeyword.BOOLEAN, PsiKeyword.DOUBLE, PsiKeyword.LONG, @@ -294,6 +300,9 @@ public class JavaStructuralSearchProfile extends StructuralSearchProfile { if (physical) { throw new UnsupportedOperationException(getClass() + " cannot create physical PSI"); } + if (MEMBER_CONTEXT.getId().equals(contextId)) { + context = PatternTreeContext.Class; + } final PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(project); if (context == PatternTreeContext.Block) { final PsiCodeBlock codeBlock = elementFactory.createCodeBlockFromText("{\n" + text + "\n}", null); @@ -414,10 +423,19 @@ public class JavaStructuralSearchProfile extends StructuralSearchProfile { return JavaCodeContextType.class; } + @NotNull + @Override + public List getPatternContexts() { + if (!Registry.is("ssr.in.editor.problem.highlighting")) return super.getPatternContexts(); + return PATTERN_CONTEXTS; + } + @NotNull @Override public PsiCodeFragment createCodeFragment(Project project, String text, String contextId) { - return JavaCodeFragmentFactory.getInstance(project).createCodeBlockCodeFragment(text, null, true); + return MEMBER_CONTEXT.getId().equals(contextId) + ? JavaCodeFragmentFactory.getInstance(project).createMemberCodeFragment(text, null, true) + : JavaCodeFragmentFactory.getInstance(project).createCodeBlockCodeFragment(text, null, true); } @Override diff --git a/platform/util/resources/misc/registry.properties b/platform/util/resources/misc/registry.properties index 061cad2b562d..bf93d2c0a23f 100644 --- a/platform/util/resources/misc/registry.properties +++ b/platform/util/resources/misc/registry.properties @@ -1545,6 +1545,8 @@ ssr.save.templates.to.ide.instead.of.project.workspace=true ssr.save.templates.to.ide.instead.of.project.workspace.description=Makes saved Structural Search templates globally available for all projects ssr.use.editor.inlays.instead.of.tool.tips=true ssr.use.editor.inlays.instead.of.tool.tips.description=Replaces filter tool tips with editor inlays in the new Structural Search dialog +ssr.in.editor.problem.highlighting=false +ssr.in.editor.problem.highlighting.description=Show location of search template problems in the editor jdk.regex.soe.workaround=true jdk.regex.soe.workaround.description=In regular expression pattern replace choice \\n|. with . (and DOT_ALL option) to prevent stack overflow during matching