mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
SSR: rework pattern context and move up into structural search profile
GitOrigin-RevId: 5468a2907780483d552fd90dee8f85ac6dfb5eb7
This commit is contained in:
committed by
intellij-monorepo-bot
parent
cbceb3ec66
commit
86c05e25f1
+4
-4
@@ -288,7 +288,7 @@ public class JavaStructuralSearchProfile extends StructuralSearchProfile {
|
||||
@NotNull PatternTreeContext context,
|
||||
@NotNull LanguageFileType fileType,
|
||||
@NotNull Language language,
|
||||
String contextName,
|
||||
String contextId,
|
||||
@NotNull Project project,
|
||||
boolean physical) {
|
||||
if (physical) {
|
||||
@@ -311,7 +311,7 @@ public class JavaStructuralSearchProfile extends StructuralSearchProfile {
|
||||
if (shouldTryExpressionPattern(result)) {
|
||||
try {
|
||||
final PsiElement[] expressionPattern =
|
||||
createPatternTree(text, PatternTreeContext.Expression, fileType, language, contextName, project, false);
|
||||
createPatternTree(text, PatternTreeContext.Expression, fileType, language, contextId, project, false);
|
||||
if (expressionPattern.length == 1) {
|
||||
return expressionPattern;
|
||||
}
|
||||
@@ -319,7 +319,7 @@ public class JavaStructuralSearchProfile extends StructuralSearchProfile {
|
||||
}
|
||||
else if (shouldTryClassPattern(result)) {
|
||||
final PsiElement[] classPattern =
|
||||
createPatternTree(text, PatternTreeContext.Class, fileType, language, contextName, project, false);
|
||||
createPatternTree(text, PatternTreeContext.Class, fileType, language, contextId, project, false);
|
||||
if (classPattern.length <= result.size()) {
|
||||
return classPattern;
|
||||
}
|
||||
@@ -416,7 +416,7 @@ public class JavaStructuralSearchProfile extends StructuralSearchProfile {
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public PsiCodeFragment createCodeFragment(Project project, String text) {
|
||||
public PsiCodeFragment createCodeFragment(Project project, String text, String contextId) {
|
||||
return JavaCodeFragmentFactory.getInstance(project).createCodeBlockCodeFragment(text, null, true);
|
||||
}
|
||||
|
||||
|
||||
@@ -31,7 +31,7 @@ public class MatchOptions implements JDOMExternalizable {
|
||||
@NotNull
|
||||
private String pattern;
|
||||
|
||||
private String myPatternContext;
|
||||
private String myPatternContextId;
|
||||
|
||||
@NonNls private static final String TEXT_ATTRIBUTE_NAME = "text";
|
||||
@NonNls private static final String LOOSE_MATCHING_ATTRIBUTE_NAME = "loose";
|
||||
@@ -65,7 +65,7 @@ public class MatchOptions implements JDOMExternalizable {
|
||||
scopeType = options.scopeType;
|
||||
scopeDescriptor = options.scopeDescriptor;
|
||||
pattern = options.pattern;
|
||||
myPatternContext = options.myPatternContext;
|
||||
myPatternContextId = options.myPatternContextId;
|
||||
}
|
||||
|
||||
public MatchOptions copy() {
|
||||
@@ -169,11 +169,11 @@ public class MatchOptions implements JDOMExternalizable {
|
||||
if (myFileType != null) {
|
||||
element.setAttribute(FILE_TYPE_ATTR_NAME, myFileType.getName());
|
||||
}
|
||||
if (myDialect != null) {
|
||||
if (myDialect != null && (myFileType == null || myFileType.getLanguage() != myDialect)) {
|
||||
element.setAttribute(DIALECT_ATTR_NAME, myDialect.getID());
|
||||
}
|
||||
if (myPatternContext != null) {
|
||||
element.setAttribute(PATTERN_CONTEXT_ATTR_NAME, myPatternContext);
|
||||
if (myPatternContextId != null) {
|
||||
element.setAttribute(PATTERN_CONTEXT_ATTR_NAME, myPatternContextId);
|
||||
}
|
||||
|
||||
if (scope != null) {
|
||||
@@ -202,7 +202,7 @@ public class MatchOptions implements JDOMExternalizable {
|
||||
|
||||
myFileType = getFileTypeByName(element.getAttributeValue(FILE_TYPE_ATTR_NAME));
|
||||
myDialect = Language.findLanguageByID(element.getAttributeValue(DIALECT_ATTR_NAME));
|
||||
myPatternContext = element.getAttributeValue(PATTERN_CONTEXT_ATTR_NAME);
|
||||
myPatternContextId = element.getAttributeValue(PATTERN_CONTEXT_ATTR_NAME);
|
||||
|
||||
final String value = element.getAttributeValue(SCOPE_TYPE);
|
||||
scopeType = (value == null) ? null : Scopes.Type.valueOf(value);
|
||||
@@ -241,12 +241,12 @@ public class MatchOptions implements JDOMExternalizable {
|
||||
if (!variableConstraints.equals(matchOptions.variableConstraints)) return false;
|
||||
if (myFileType != matchOptions.myFileType) return false;
|
||||
if (!Objects.equals(myDialect, matchOptions.myDialect)) return false;
|
||||
if (!Objects.equals(myPatternContext, matchOptions.myPatternContext)) return false;
|
||||
if (!Objects.equals(myPatternContextId, matchOptions.myPatternContextId)) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
public int hashCode() {
|
||||
int result = (looseMatching ? 1 : 0);
|
||||
result = 29 * result + (recursiveSearch ? 1 : 0);
|
||||
result = 29 * result + (caseSensitiveMatch ? 1 : 0);
|
||||
@@ -256,7 +256,7 @@ public int hashCode() {
|
||||
result = 29 * result + scope.hashCode();
|
||||
if (myFileType != null) result = 29 * result + myFileType.hashCode();
|
||||
if (myDialect != null) result = 29 * result + myDialect.hashCode();
|
||||
if (myPatternContext != null) result = 29 * result + myPatternContext.hashCode();
|
||||
if (myPatternContextId != null) result = 29 * result + myPatternContextId.hashCode();
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -284,11 +284,12 @@ public int hashCode() {
|
||||
myDialect = dialect;
|
||||
}
|
||||
|
||||
public String getPatternContext() {
|
||||
return myPatternContext;
|
||||
public PatternContext getPatternContext() {
|
||||
if (myPatternContextId == null) return null;
|
||||
return StructuralSearchUtil.findPatternContextByID(myPatternContextId, getDialect());
|
||||
}
|
||||
|
||||
public void setPatternContext(String patternContext) {
|
||||
myPatternContext = patternContext;
|
||||
public void setPatternContext(PatternContext patternContext) {
|
||||
myPatternContextId = (patternContext == null) ? null : patternContext.getId();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
// 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.structuralsearch;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* @author Bas Leijdekkers
|
||||
*/
|
||||
public final class PatternContext implements Comparable<PatternContext> {
|
||||
|
||||
public final String myID;
|
||||
private final String myDisplayName;
|
||||
|
||||
public PatternContext(@NotNull String ID, String displayName) {
|
||||
myID = ID;
|
||||
myDisplayName = displayName;
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
|
||||
final PatternContext other = (PatternContext)o;
|
||||
return myID.equals(other.myID) && myDisplayName.equals(other.myDisplayName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return 31 * myID.hashCode() + myDisplayName.hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(@NotNull PatternContext o) {
|
||||
return myDisplayName.compareTo(o.myDisplayName);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public String getId() {
|
||||
return myID;
|
||||
}
|
||||
|
||||
public String getDisplayName() {
|
||||
return myDisplayName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return myDisplayName + " (" + myID + ')';
|
||||
}
|
||||
}
|
||||
+73
-16
@@ -22,6 +22,7 @@ import com.intellij.structuralsearch.plugin.replace.impl.ReplacementBuilder;
|
||||
import com.intellij.structuralsearch.plugin.replace.impl.Replacer;
|
||||
import com.intellij.structuralsearch.plugin.ui.Configuration;
|
||||
import com.intellij.structuralsearch.plugin.ui.UIUtil;
|
||||
import com.intellij.util.SmartList;
|
||||
import org.jetbrains.annotations.Contract;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@@ -36,6 +37,7 @@ import java.util.List;
|
||||
public abstract class StructuralSearchProfile {
|
||||
public static final ExtensionPointName<StructuralSearchProfile> EP_NAME =
|
||||
ExtensionPointName.create("com.intellij.structuralsearch.profile");
|
||||
protected static final String PATTERN_PLACEHOLDER = "$$PATTERN_PLACEHOLDER$$";
|
||||
|
||||
public abstract void compile(PsiElement[] elements, @NotNull GlobalCompilingVisitor globalVisitor);
|
||||
|
||||
@@ -59,13 +61,52 @@ public abstract class StructuralSearchProfile {
|
||||
@NotNull PatternTreeContext context,
|
||||
@NotNull LanguageFileType fileType,
|
||||
@NotNull Language language,
|
||||
@Nullable String contextName,
|
||||
@Nullable String contextId,
|
||||
@NotNull Project project,
|
||||
boolean physical) {
|
||||
final String name = "__dummy." + fileType.getDefaultExtension();
|
||||
final PsiFile file = PsiFileFactory.getInstance(project).createFileFromText(name, language, text, physical, true);
|
||||
final String strContext = getContext(text, language, contextId);
|
||||
final int offset = strContext.indexOf(PATTERN_PLACEHOLDER);
|
||||
|
||||
return file != null ? file.getChildren() : PsiElement.EMPTY_ARRAY;
|
||||
final int patternLength = text.length();
|
||||
final String patternInContext = strContext.replace(PATTERN_PLACEHOLDER, text);
|
||||
|
||||
final String name = "__dummy." + fileType.getDefaultExtension();
|
||||
final PsiFile file = PsiFileFactory.getInstance(project).createFileFromText(name, language, patternInContext, physical, true);
|
||||
if (file == null) {
|
||||
return PsiElement.EMPTY_ARRAY;
|
||||
}
|
||||
|
||||
final List<PsiElement> result = new SmartList<>();
|
||||
|
||||
PsiElement element = file.findElementAt(offset);
|
||||
if (element == null) {
|
||||
return PsiElement.EMPTY_ARRAY;
|
||||
}
|
||||
|
||||
PsiElement topElement = element;
|
||||
element = element.getParent();
|
||||
|
||||
while (element != null) {
|
||||
if (element.getTextRange().getStartOffset() == offset && element.getTextLength() <= patternLength) {
|
||||
topElement = element;
|
||||
}
|
||||
element = element.getParent();
|
||||
}
|
||||
|
||||
if (topElement instanceof PsiFile) {
|
||||
return topElement.getChildren();
|
||||
}
|
||||
|
||||
final int endOffset = offset + patternLength;
|
||||
result.add(topElement);
|
||||
topElement = topElement.getNextSibling();
|
||||
|
||||
while (topElement != null && topElement.getTextRange().getEndOffset() <= endOffset) {
|
||||
result.add(topElement);
|
||||
topElement = topElement.getNextSibling();
|
||||
}
|
||||
|
||||
return result.toArray(PsiElement.EMPTY_ARRAY);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -89,8 +130,18 @@ public abstract class StructuralSearchProfile {
|
||||
return createPatternTree(text, context, (LanguageFileType)fileType, language, contextName, project, physical);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public List<PatternContext> getPatternContexts() {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
protected String getContext(@NotNull String pattern, @Nullable Language language, @Nullable String contextId) {
|
||||
return PATTERN_PLACEHOLDER;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public PsiCodeFragment createCodeFragment(Project project, String text) {
|
||||
public PsiCodeFragment createCodeFragment(Project project, String text, String contextId) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -129,7 +180,7 @@ public abstract class StructuralSearchProfile {
|
||||
|
||||
public String getText(PsiElement match, int start, int end) {
|
||||
final String matchText = match.getText();
|
||||
if (start==0 && end==-1) return matchText;
|
||||
if (start == 0 && end == -1) return matchText;
|
||||
return matchText.substring(start, end == -1 ? matchText.length() : end);
|
||||
}
|
||||
|
||||
@@ -143,7 +194,7 @@ public abstract class StructuralSearchProfile {
|
||||
}
|
||||
return element.getText();
|
||||
}
|
||||
|
||||
|
||||
public String getMeaningfulText(PsiElement element) {
|
||||
return getTypedVarString(element);
|
||||
}
|
||||
@@ -192,7 +243,8 @@ public abstract class StructuralSearchProfile {
|
||||
if (buf.length() > 0) {
|
||||
if (info.isArgumentContext()) {
|
||||
buf.append(',');
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
final PsiElement sibling = currentElement.getPrevSibling();
|
||||
buf.append(sibling instanceof PsiWhiteSpace ? sibling.getText() : " ");
|
||||
}
|
||||
@@ -202,7 +254,8 @@ public abstract class StructuralSearchProfile {
|
||||
removeSemicolon = currentElement instanceof PsiComment;
|
||||
}
|
||||
replacementString = buf.toString();
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
if (info.isStatementContext()) {
|
||||
removeSemicolon = match.getMatch() instanceof PsiComment;
|
||||
}
|
||||
@@ -211,7 +264,7 @@ public abstract class StructuralSearchProfile {
|
||||
|
||||
offset = Replacer.insertSubstitution(result, offset, info, replacementString);
|
||||
if (info.isStatementContext() &&
|
||||
(removeSemicolon || StringUtil.endsWithChar(replacementString, ';') || StringUtil.endsWithChar(replacementString, '}'))) {
|
||||
(removeSemicolon || StringUtil.endsWithChar(replacementString, ';') || StringUtil.endsWithChar(replacementString, '}'))) {
|
||||
final int start = info.getStartIndex() + offset;
|
||||
result.delete(start, start + 1);
|
||||
offset--;
|
||||
@@ -255,10 +308,10 @@ public abstract class StructuralSearchProfile {
|
||||
* Override this method to influence which UI controls are shown when editing the constraints of the specified variable.
|
||||
*
|
||||
* @param constraintName the name of the constraint controls for which applicability is considered.
|
||||
* See {@link UIUtil} for predefined constraint names
|
||||
* @param variableNode the psi element corresponding to the current variable
|
||||
* @param completePattern true, if the current variableNode encompasses the complete pattern. The variableNode can also be null in this case.
|
||||
* @param target true, if the current variableNode is the target of the search
|
||||
* See {@link UIUtil} for predefined constraint names
|
||||
* @param variableNode the psi element corresponding to the current variable
|
||||
* @param completePattern true, if the current variableNode encompasses the complete pattern. The variableNode can also be null in this case.
|
||||
* @param target true, if the current variableNode is the target of the search
|
||||
* @return true, if the requested constraint is applicable and the corresponding UI should be shown when editing the variable; false otherwise
|
||||
*/
|
||||
public boolean isApplicableConstraint(String constraintName, @Nullable PsiElement variableNode, boolean completePattern, boolean target) {
|
||||
@@ -267,12 +320,16 @@ public abstract class StructuralSearchProfile {
|
||||
if (target) return false;
|
||||
case UIUtil.MAXIMUM_UNLIMITED:
|
||||
case UIUtil.TEXT:
|
||||
case UIUtil.REFERENCE: return !completePattern;
|
||||
case UIUtil.REFERENCE:
|
||||
return !completePattern;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public final boolean isApplicableConstraint(String constraintName, List<? extends PsiElement> nodes, boolean completePattern, boolean target) {
|
||||
public final boolean isApplicableConstraint(String constraintName,
|
||||
List<? extends PsiElement> nodes,
|
||||
boolean completePattern,
|
||||
boolean target) {
|
||||
if (nodes.isEmpty()) {
|
||||
return isApplicableConstraint(constraintName, (PsiElement)null, completePattern, target);
|
||||
}
|
||||
|
||||
+3
-74
@@ -21,17 +21,17 @@ import com.intellij.psi.tree.TokenSet;
|
||||
import com.intellij.structuralsearch.impl.matcher.CompiledPattern;
|
||||
import com.intellij.structuralsearch.impl.matcher.GlobalMatchingVisitor;
|
||||
import com.intellij.structuralsearch.impl.matcher.MatchContext;
|
||||
import com.intellij.structuralsearch.impl.matcher.PatternTreeContext;
|
||||
import com.intellij.structuralsearch.impl.matcher.compiler.GlobalCompilingVisitor;
|
||||
import com.intellij.structuralsearch.impl.matcher.handlers.*;
|
||||
import com.intellij.structuralsearch.impl.matcher.iterators.SsrFilteringNodeIterator;
|
||||
import com.intellij.structuralsearch.impl.matcher.strategies.MatchingStrategy;
|
||||
import com.intellij.structuralsearch.plugin.replace.ReplaceOptions;
|
||||
import com.intellij.util.ArrayUtilRt;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
@@ -39,7 +39,6 @@ import java.util.regex.Pattern;
|
||||
*/
|
||||
public abstract class StructuralSearchProfileBase extends StructuralSearchProfile {
|
||||
private static final String DELIMITER_CHARS = ",;.[]{}():";
|
||||
protected static final String PATTERN_PLACEHOLDER = "$$PATTERN_PLACEHOLDER$$";
|
||||
|
||||
@Override
|
||||
public void compile(PsiElement[] elements, @NotNull final GlobalCompilingVisitor globalVisitor) {
|
||||
@@ -179,66 +178,6 @@ public abstract class StructuralSearchProfileBase extends StructuralSearchProfil
|
||||
@NotNull
|
||||
protected abstract LanguageFileType getFileType();
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public PsiElement[] createPatternTree(@NotNull String text,
|
||||
@NotNull PatternTreeContext context,
|
||||
@NotNull LanguageFileType fileType,
|
||||
@NotNull Language language,
|
||||
@Nullable String contextName,
|
||||
@NotNull Project project,
|
||||
boolean physical) {
|
||||
if (context == PatternTreeContext.Block) {
|
||||
final String strContext = getContext(text, language, contextName);
|
||||
if (strContext == null) {
|
||||
return PsiElement.EMPTY_ARRAY;
|
||||
}
|
||||
final int offset = strContext.indexOf(PATTERN_PLACEHOLDER);
|
||||
|
||||
final int patternLength = text.length();
|
||||
final String patternInContext = strContext.replace(PATTERN_PLACEHOLDER, text);
|
||||
|
||||
final String name = "__dummy." + fileType.getDefaultExtension();
|
||||
final PsiFile file = PsiFileFactory.getInstance(project).createFileFromText(name, language, patternInContext, physical, true);
|
||||
if (file == null) {
|
||||
return PsiElement.EMPTY_ARRAY;
|
||||
}
|
||||
|
||||
final List<PsiElement> result = new ArrayList<>();
|
||||
|
||||
PsiElement element = file.findElementAt(offset);
|
||||
if (element == null) {
|
||||
return PsiElement.EMPTY_ARRAY;
|
||||
}
|
||||
|
||||
PsiElement topElement = element;
|
||||
element = element.getParent();
|
||||
|
||||
while (element != null) {
|
||||
if (element.getTextRange().getStartOffset() == offset && element.getTextLength() <= patternLength) {
|
||||
topElement = element;
|
||||
}
|
||||
element = element.getParent();
|
||||
}
|
||||
|
||||
if (topElement instanceof PsiFile) {
|
||||
return topElement.getChildren();
|
||||
}
|
||||
|
||||
final int endOffset = offset + patternLength;
|
||||
result.add(topElement);
|
||||
topElement = topElement.getNextSibling();
|
||||
|
||||
while (topElement != null && topElement.getTextRange().getEndOffset() <= endOffset) {
|
||||
result.add(topElement);
|
||||
topElement = topElement.getNextSibling();
|
||||
}
|
||||
|
||||
return result.toArray(PsiElement.EMPTY_ARRAY);
|
||||
}
|
||||
return super.createPatternTree(text, context, fileType, language, contextName, project, physical);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void checkReplacementPattern(Project project, ReplaceOptions options) {}
|
||||
|
||||
@@ -247,16 +186,6 @@ public abstract class StructuralSearchProfileBase extends StructuralSearchProfil
|
||||
return new DocumentBasedReplaceHandler(project);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public String[] getContextNames() {
|
||||
return ArrayUtilRt.EMPTY_STRING_ARRAY;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
protected String getContext(@NotNull String pattern, @Nullable Language language, @Nullable String contextName) {
|
||||
return PATTERN_PLACEHOLDER;
|
||||
}
|
||||
|
||||
static boolean canBePatternVariable(PsiElement element) {
|
||||
// can be leaf element! (ex. var a = 1 <-> var $a$ = 1)
|
||||
if (element instanceof LeafElement) {
|
||||
|
||||
+18
@@ -225,4 +225,22 @@ public class StructuralSearchUtil {
|
||||
public static String normalize(@NotNull String text) {
|
||||
return stripAccents(normalizeWhiteSpace(text));
|
||||
}
|
||||
|
||||
public static PatternContext findPatternContextByID(String id, Language language) {
|
||||
return findPatternContextByID(id, getProfileByLanguage(language));
|
||||
}
|
||||
|
||||
public static PatternContext findPatternContextByID(String id, StructuralSearchProfile profile) {
|
||||
if (profile == null) {
|
||||
return null;
|
||||
}
|
||||
final List<PatternContext> patternContexts = profile.getPatternContexts();
|
||||
if (patternContexts.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
if (id == null) {
|
||||
return patternContexts.get(0);
|
||||
}
|
||||
return patternContexts.stream().filter(context -> context.getId().equals(id)).findFirst().orElse(patternContexts.get(0));
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -85,7 +85,7 @@ public class XmlStructuralSearchProfile extends StructuralSearchProfile {
|
||||
@NotNull PatternTreeContext context,
|
||||
@NotNull LanguageFileType fileType,
|
||||
@NotNull Language language,
|
||||
String contextName,
|
||||
String contextId,
|
||||
@NotNull Project project,
|
||||
boolean physical) {
|
||||
text = context == PatternTreeContext.File ? text : "<QQQ>" + text + "</QQQ>";
|
||||
|
||||
+1
-1
@@ -86,7 +86,7 @@ public abstract class CompiledPattern {
|
||||
@NotNull
|
||||
public String getTypedVarString(PsiElement element) {
|
||||
final StructuralSearchProfile profile = StructuralSearchUtil.getProfileByPsiElement(element);
|
||||
String typedVarString = (profile == null) ? element.getText() : profile.getTypedVarString(element);
|
||||
final String typedVarString = (profile == null) ? element.getText() : profile.getTypedVarString(element);
|
||||
return typedVarString.trim();
|
||||
}
|
||||
|
||||
|
||||
+4
-2
@@ -5,6 +5,7 @@ import com.intellij.lang.Language;
|
||||
import com.intellij.openapi.fileTypes.LanguageFileType;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.structuralsearch.PatternContext;
|
||||
import com.intellij.structuralsearch.StructuralSearchProfile;
|
||||
import com.intellij.structuralsearch.StructuralSearchUtil;
|
||||
|
||||
@@ -33,7 +34,7 @@ public class MatcherImplUtil {
|
||||
PatternTreeContext context,
|
||||
LanguageFileType fileType,
|
||||
Language language,
|
||||
String contextName,
|
||||
PatternContext patternContext,
|
||||
Project project,
|
||||
boolean physical) {
|
||||
if (language == null) {
|
||||
@@ -41,7 +42,8 @@ public class MatcherImplUtil {
|
||||
}
|
||||
final StructuralSearchProfile profile = StructuralSearchUtil.getProfileByLanguage(language);
|
||||
if (profile != null) {
|
||||
return profile.createPatternTree(text, context, fileType, language, contextName, project, physical);
|
||||
final String contextId = (patternContext == null) ? null : patternContext.getId();
|
||||
return profile.createPatternTree(text, context, fileType, language, contextId, project, physical);
|
||||
}
|
||||
return PsiElement.EMPTY_ARRAY;
|
||||
}
|
||||
|
||||
+1
-1
@@ -99,7 +99,7 @@ public final class ReplacementPreviewDialog extends DialogWrapper {
|
||||
PsiFile file = null;
|
||||
final StructuralSearchProfile profile = StructuralSearchUtil.getProfileByFileType(myFileType);
|
||||
if (profile != null) {
|
||||
file = profile.createCodeFragment(project, "");
|
||||
file = profile.createCodeFragment(project, "", null);
|
||||
}
|
||||
|
||||
if (file != null) {
|
||||
|
||||
+1
-1
@@ -574,7 +574,7 @@ class EditVarConstraintsDialog extends DialogWrapper {
|
||||
// there is no right way to create a code fragment for generic language, so we use this hole since we need extend resolve scope
|
||||
for (StructuralSearchProfile profile : StructuralSearchProfile.EP_NAME.getExtensions()) {
|
||||
if (profile.isMyLanguage(groovy)) {
|
||||
final PsiCodeFragment fragment = Objects.requireNonNull(profile.createCodeFragment(project, text));
|
||||
final PsiCodeFragment fragment = Objects.requireNonNull(profile.createCodeFragment(project, text, null));
|
||||
fragment.forceResolveScope(new StructuralSearchScriptScope(myProject));
|
||||
doc = PsiDocumentManager.getInstance(project).getDocument(fragment);
|
||||
break;
|
||||
|
||||
+30
-53
@@ -4,6 +4,7 @@ package com.intellij.structuralsearch.plugin.ui;
|
||||
import com.intellij.lang.Language;
|
||||
import com.intellij.openapi.fileTypes.LanguageFileType;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.structuralsearch.PatternContext;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@@ -21,20 +22,16 @@ public class FileTypeInfo {
|
||||
|
||||
private final LanguageFileType myFileType;
|
||||
private final Language myDialect;
|
||||
private final String myContext;
|
||||
private final boolean myEnabled;
|
||||
private final PatternContext myContext;
|
||||
private final boolean myNested;
|
||||
private final String myDescription;
|
||||
|
||||
public FileTypeInfo(@NotNull LanguageFileType fileType,
|
||||
@Nullable Language dialect,
|
||||
@Nullable String context,
|
||||
boolean enabled,
|
||||
boolean duplicated) {
|
||||
public FileTypeInfo(@NotNull LanguageFileType fileType, @NotNull Language dialect, @Nullable PatternContext context, boolean nested) {
|
||||
myFileType = fileType;
|
||||
myDialect = dialect;
|
||||
myContext = context;
|
||||
myEnabled = enabled;
|
||||
myDescription = getDescription(fileType, duplicated);
|
||||
myNested = nested;
|
||||
myDescription = getDescription(fileType);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -48,62 +45,42 @@ public class FileTypeInfo {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public String getContext() {
|
||||
public PatternContext getContext() {
|
||||
return myContext;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public String getText() {
|
||||
if (myDialect != null) {
|
||||
return myDialect.getDisplayName();
|
||||
}
|
||||
if (myContext != null) {
|
||||
return myContext + " Context";
|
||||
}
|
||||
return myFileType.getName();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public String getSearchText() {
|
||||
if (myDialect != null) {
|
||||
return myDialect.getDisplayName();
|
||||
}
|
||||
return myFileType.getName();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public String getFullText() {
|
||||
if (myDialect != null) {
|
||||
return myDescription + " - " + myDialect.getDisplayName();
|
||||
}
|
||||
if (myContext != null) {
|
||||
return myDescription + " - " + myContext + " Context";
|
||||
if (myNested) {
|
||||
if (myDialect != null && myDialect != myFileType.getLanguage()) {
|
||||
return myDialect.getDisplayName();
|
||||
}
|
||||
if (myContext != null) {
|
||||
return myDescription + " - " + myContext.getDisplayName();
|
||||
}
|
||||
}
|
||||
return myDescription;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public String getSearchText() {
|
||||
return (myDialect != null) ? myDialect.getDisplayName() : myFileType.getName();
|
||||
}
|
||||
|
||||
public boolean isNested() {
|
||||
return myDialect != null || myContext != null;
|
||||
return myNested;
|
||||
}
|
||||
|
||||
public boolean isEnabled() {
|
||||
return myEnabled;
|
||||
}
|
||||
|
||||
public boolean isEqualTo(@NotNull LanguageFileType fileType, @Nullable Language dialect, @Nullable String context) {
|
||||
return Objects.equals(myFileType, fileType) &&
|
||||
Objects.equals(myDialect, dialect) &&
|
||||
Objects.equals(myContext, context);
|
||||
public boolean isEqualTo(@NotNull LanguageFileType fileType, @Nullable Language dialect, @Nullable PatternContext context) {
|
||||
return (myFileType == fileType)
|
||||
&& (dialect == null || myDialect == dialect)
|
||||
&& (context == null || myContext == context);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static String getDescription(@NotNull LanguageFileType fileType, boolean duplicated) {
|
||||
private static String getDescription(@NotNull LanguageFileType fileType) {
|
||||
final String description = fileType.getDescription();
|
||||
final String trimmedDescription = StringUtil.capitalizeWords(CLEANUP.matcher(description).replaceAll(""), true);
|
||||
if (!duplicated) {
|
||||
return trimmedDescription;
|
||||
}
|
||||
return trimmedDescription + " (" + fileType.getName() + ")";
|
||||
return StringUtil.capitalizeWords(CLEANUP.matcher(description).replaceAll(""), true);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -111,9 +88,9 @@ public class FileTypeInfo {
|
||||
if (this == o) return true;
|
||||
if (!(o instanceof FileTypeInfo)) return false;
|
||||
final FileTypeInfo info = (FileTypeInfo)o;
|
||||
return Objects.equals(myFileType, info.myFileType) &&
|
||||
Objects.equals(myDialect, info.myDialect) &&
|
||||
Objects.equals(myContext, info.myContext);
|
||||
return myFileType == info.myFileType
|
||||
&& myDialect == info.myDialect
|
||||
&& myContext == info.myContext;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -123,6 +100,6 @@ public class FileTypeInfo {
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return getFullText();
|
||||
return getText();
|
||||
}
|
||||
}
|
||||
|
||||
+15
-47
@@ -3,11 +3,10 @@ package com.intellij.structuralsearch.plugin.ui;
|
||||
|
||||
import com.intellij.lang.Language;
|
||||
import com.intellij.lang.LanguageUtil;
|
||||
import com.intellij.openapi.fileTypes.FileType;
|
||||
import com.intellij.openapi.fileTypes.LanguageFileType;
|
||||
import com.intellij.openapi.ui.ComboBox;
|
||||
import com.intellij.structuralsearch.PatternContext;
|
||||
import com.intellij.structuralsearch.StructuralSearchProfile;
|
||||
import com.intellij.structuralsearch.StructuralSearchProfileBase;
|
||||
import com.intellij.structuralsearch.StructuralSearchUtil;
|
||||
import com.intellij.ui.LayeredIcon;
|
||||
import com.intellij.ui.SimpleListCellRenderer;
|
||||
@@ -42,7 +41,9 @@ public class FileTypeSelector extends ComboBox<FileTypeInfo> {
|
||||
return info != null ? info.getFileType() : null;
|
||||
}
|
||||
|
||||
public void setSelectedItem(@NotNull LanguageFileType type, @Nullable Language dialect, @Nullable String context) {
|
||||
public void setSelectedItem(@NotNull LanguageFileType type,
|
||||
@Nullable Language dialect,
|
||||
@Nullable PatternContext context) {
|
||||
final DefaultComboBoxModel<FileTypeInfo> model = (DefaultComboBoxModel<FileTypeInfo>)getModel();
|
||||
for (int i = 0; i < model.getSize(); i++) {
|
||||
final FileTypeInfo info = model.getElementAt(i);
|
||||
@@ -53,23 +54,6 @@ public class FileTypeSelector extends ComboBox<FileTypeInfo> {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSelectedItem(Object anObject) {
|
||||
if (anObject instanceof FileTypeInfo) {
|
||||
final FileTypeInfo selectedInfo = (FileTypeInfo)anObject;
|
||||
if (!selectedInfo.isEnabled()) {
|
||||
final MyComboBoxModel model = (MyComboBoxModel)getModel();
|
||||
final int index = model.getIndexOf(selectedInfo);
|
||||
if (index >= 0 && index + 1 < model.getSize()) {
|
||||
final FileTypeInfo nextInfo = model.getElementAt(index + 1);
|
||||
super.setSelectedItem(nextInfo);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
super.setSelectedItem(anObject);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static DefaultComboBoxModel<FileTypeInfo> createModel() {
|
||||
final List<LanguageFileType> types = new ArrayList<>();
|
||||
@@ -81,30 +65,25 @@ public class FileTypeSelector extends ComboBox<FileTypeInfo> {
|
||||
Collections.sort(types, (o1, o2) -> o1.getDescription().compareToIgnoreCase(o2.getDescription()));
|
||||
final List<FileTypeInfo> infos = new ArrayList<>();
|
||||
for (LanguageFileType fileType : types) {
|
||||
final boolean duplicated = isDuplicated(fileType, types);
|
||||
|
||||
final StructuralSearchProfile profile = StructuralSearchUtil.getProfileByFileType(fileType);
|
||||
assert profile != null;
|
||||
if (profile instanceof StructuralSearchProfileBase) {
|
||||
final String[] contextNames = ((StructuralSearchProfileBase)profile).getContextNames();
|
||||
if (contextNames.length != 0) {
|
||||
Arrays.sort(contextNames);
|
||||
infos.add(new FileTypeInfo(fileType, null, null, false, duplicated));
|
||||
for (String contextName: contextNames) {
|
||||
infos.add(new FileTypeInfo(fileType, null, contextName, true, duplicated));
|
||||
}
|
||||
continue; // proceed with the next file type
|
||||
final Language language = fileType.getLanguage();
|
||||
final List<PatternContext> patternContexts = new ArrayList<>(profile.getPatternContexts());
|
||||
if (!patternContexts.isEmpty()) {
|
||||
infos.add(new FileTypeInfo(fileType, language, patternContexts.get(0), false));
|
||||
for (int i = 1; i < patternContexts.size(); i++) {
|
||||
infos.add(new FileTypeInfo(fileType, language, patternContexts.get(i), true));
|
||||
}
|
||||
continue; // proceed with the next file type
|
||||
}
|
||||
|
||||
infos.add(new FileTypeInfo(fileType, null, null, true, duplicated));
|
||||
infos.add(new FileTypeInfo(fileType, language, null, false));
|
||||
|
||||
final Language language = fileType.getLanguage();
|
||||
final Language[] languageDialects = LanguageUtil.getLanguageDialects(language);
|
||||
Arrays.sort(languageDialects, Comparator.comparing(Language::getDisplayName));
|
||||
for (Language dialect : languageDialects) {
|
||||
if (profile.isMyLanguage(dialect)) {
|
||||
infos.add(new FileTypeInfo(fileType, dialect, null, true, duplicated));
|
||||
infos.add(new FileTypeInfo(fileType, dialect, null, true));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -112,11 +91,6 @@ public class FileTypeSelector extends ComboBox<FileTypeInfo> {
|
||||
return new MyComboBoxModel(infos);
|
||||
}
|
||||
|
||||
private static boolean isDuplicated(@NotNull LanguageFileType fileType, @NotNull List<? extends FileType> types) {
|
||||
final String description = fileType.getDescription();
|
||||
return types.stream().anyMatch(type -> type != fileType && description.equals(type.getDescription()));
|
||||
}
|
||||
|
||||
private static class MyComboBoxModel extends DefaultComboBoxModel<FileTypeInfo> {
|
||||
MyComboBoxModel(List<FileTypeInfo> infos) {
|
||||
super(infos.toArray(FileTypeInfo.EMPTY_ARRAY));
|
||||
@@ -134,14 +108,8 @@ public class FileTypeSelector extends ComboBox<FileTypeInfo> {
|
||||
if (value == null) {
|
||||
return;
|
||||
}
|
||||
if (value.isNested() && index >= 0) {
|
||||
setIcon(WIDE_EMPTY_ICON);
|
||||
setText(value.getText());
|
||||
}
|
||||
else {
|
||||
setIcon(getFileTypeIcon(value));
|
||||
setText(value.getFullText());
|
||||
}
|
||||
setIcon(value.isNested() && index >= 0 ? WIDE_EMPTY_ICON : getFileTypeIcon(value));
|
||||
setText(value.getText());
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
||||
+1
-1
@@ -79,7 +79,7 @@ public class SearchDialog extends DialogWrapper {
|
||||
|
||||
@NonNls private LanguageFileType ourFtSearchVariant = StructuralSearchUtil.getDefaultFileType();
|
||||
private static Language ourDialect = null;
|
||||
private static String ourContext = null;
|
||||
private static PatternContext ourContext = null;
|
||||
|
||||
private final boolean myShowScopePanel;
|
||||
private final boolean myRunFindActionOnClose;
|
||||
|
||||
+15
-7
@@ -119,7 +119,7 @@ public class StructuralSearchDialog extends DialogWrapper {
|
||||
Configuration myConfiguration;
|
||||
@NonNls LanguageFileType myFileType = StructuralSearchUtil.getDefaultFileType();
|
||||
Language myDialect = null;
|
||||
String myContext = null;
|
||||
PatternContext myPatternContext = null;
|
||||
private final List<RangeHighlighter> myRangeHighlighters = new SmartList<>();
|
||||
|
||||
// ui management
|
||||
@@ -193,7 +193,7 @@ public class StructuralSearchDialog extends DialogWrapper {
|
||||
private EditorTextField createEditor() {
|
||||
final StructuralSearchProfile profile = StructuralSearchUtil.getProfileByFileType(myFileType);
|
||||
assert profile != null;
|
||||
final Document document = UIUtil.createDocument(getProject(), myFileType, myDialect, "", profile);
|
||||
final Document document = UIUtil.createDocument(getProject(), myFileType, myDialect, myPatternContext, "", profile);
|
||||
|
||||
final EditorTextField textField = new EditorTextField(document, getProject(), myFileType, false, false) {
|
||||
@Override
|
||||
@@ -494,9 +494,17 @@ public class StructuralSearchDialog extends DialogWrapper {
|
||||
myRecursive.setVisible(!myReplace);
|
||||
myMatchCase = new JCheckBox(FindBundle.message("find.popup.case.sensitive"), true);
|
||||
myFileType = UIUtil.detectFileType(mySearchContext);
|
||||
myDialect = myFileType.getLanguage();
|
||||
final StructuralSearchProfile profile = StructuralSearchUtil.getProfileByFileType(myFileType);
|
||||
if (profile != null) {
|
||||
final List<PatternContext> contexts = profile.getPatternContexts();
|
||||
if (!contexts.isEmpty()) {
|
||||
myPatternContext = contexts.get(0);
|
||||
}
|
||||
}
|
||||
myFileTypesComboBox = new FileTypeSelector();
|
||||
myFileTypesComboBox.setMinimumAndPreferredWidth(200);
|
||||
myFileTypesComboBox.setSelectedItem(myFileType, myDialect, myContext);
|
||||
myFileTypesComboBox.setSelectedItem(myFileType, myDialect, myPatternContext);
|
||||
myFileTypesComboBox.addItemListener(new ItemListener() {
|
||||
@Override
|
||||
public void itemStateChanged(ItemEvent e) {
|
||||
@@ -505,14 +513,14 @@ public class StructuralSearchDialog extends DialogWrapper {
|
||||
if (item == null) return;
|
||||
myFileType = item.getFileType();
|
||||
myDialect = item.getDialect();
|
||||
myContext = item.getContext();
|
||||
myPatternContext = item.getContext();
|
||||
final StructuralSearchProfile profile = StructuralSearchUtil.getProfileByFileType(myFileType);
|
||||
assert profile != null;
|
||||
final Document searchDocument =
|
||||
UIUtil.createDocument(getProject(), myFileType, myDialect, mySearchCriteriaEdit.getText(), profile);
|
||||
UIUtil.createDocument(getProject(), myFileType, myDialect, myPatternContext, mySearchCriteriaEdit.getText(), profile);
|
||||
mySearchCriteriaEdit.setNewDocumentAndFileType(myFileType, searchDocument);
|
||||
final Document replaceDocument =
|
||||
UIUtil.createDocument(getProject(), myFileType, myDialect, myReplaceCriteriaEdit.getText(), profile);
|
||||
UIUtil.createDocument(getProject(), myFileType, myDialect, myPatternContext, myReplaceCriteriaEdit.getText(), profile);
|
||||
myReplaceCriteriaEdit.setNewDocumentAndFileType(myFileType, replaceDocument);
|
||||
myFilterPanel.setProfile(profile);
|
||||
initiateValidation();
|
||||
@@ -1020,7 +1028,7 @@ public class StructuralSearchDialog extends DialogWrapper {
|
||||
}
|
||||
matchOptions.setFileType(myFileType);
|
||||
matchOptions.setDialect(myDialect);
|
||||
matchOptions.setPatternContext(myContext);
|
||||
matchOptions.setPatternContext(myPatternContext);
|
||||
matchOptions.setSearchPattern(getPattern(mySearchCriteriaEdit));
|
||||
matchOptions.setCaseSensitiveMatch(myMatchCase.isSelected());
|
||||
|
||||
|
||||
+10
-6
@@ -258,10 +258,10 @@ public class UIUtil {
|
||||
|
||||
public static LanguageFileType detectFileType(@NotNull SearchContext searchContext) {
|
||||
final PsiFile file = searchContext.getFile();
|
||||
PsiElement context = file;
|
||||
PsiElement context = null;
|
||||
|
||||
final Editor editor = searchContext.getEditor();
|
||||
if (editor != null && context != null) {
|
||||
if (editor != null && file != null) {
|
||||
final int offset = editor.getCaretModel().getOffset();
|
||||
context = InjectedLanguageManager.getInstance(searchContext.getProject()).findInjectedElementAt(file, offset);
|
||||
if (context == null) {
|
||||
@@ -270,6 +270,9 @@ public class UIUtil {
|
||||
if (context != null) {
|
||||
context = context.getParent();
|
||||
}
|
||||
if (context == null) {
|
||||
context = file;
|
||||
}
|
||||
}
|
||||
if (context != null) {
|
||||
final Language language = context.getLanguage();
|
||||
@@ -283,9 +286,10 @@ public class UIUtil {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static Document createDocument(@NotNull Project project, @NotNull LanguageFileType fileType, Language dialect, @NotNull String text,
|
||||
@NotNull StructuralSearchProfile profile) {
|
||||
PsiFile codeFragment = profile.createCodeFragment(project, text);
|
||||
public static Document createDocument(@NotNull Project project, @NotNull LanguageFileType fileType, Language dialect,
|
||||
PatternContext patternContext, @NotNull String text, @NotNull StructuralSearchProfile profile) {
|
||||
final String contextId = (patternContext == null) ? null : patternContext.getId();
|
||||
PsiFile codeFragment = profile.createCodeFragment(project, text, contextId);
|
||||
if (codeFragment == null) {
|
||||
codeFragment = createFileFragment(project, fileType, dialect, text);
|
||||
}
|
||||
@@ -302,7 +306,7 @@ public class UIUtil {
|
||||
@NotNull
|
||||
public static Editor createEditor(@NotNull Project project, @NotNull LanguageFileType fileType, Language dialect, @NotNull String text,
|
||||
@NotNull StructuralSearchProfile profile) {
|
||||
PsiFile codeFragment = profile.createCodeFragment(project, text);
|
||||
PsiFile codeFragment = profile.createCodeFragment(project, text, null);
|
||||
if (codeFragment == null) {
|
||||
codeFragment = createFileFragment(project, fileType, dialect, text);
|
||||
}
|
||||
|
||||
+15
-8
@@ -5,8 +5,11 @@ import com.intellij.codeInsight.template.TemplateContextType;
|
||||
import com.intellij.lang.Language;
|
||||
import com.intellij.openapi.fileTypes.LanguageFileType;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.PsiCodeFragment;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiIdentifier;
|
||||
import com.intellij.psi.tree.TokenSet;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.plugins.groovy.GroovyFileType;
|
||||
@@ -14,12 +17,15 @@ import org.jetbrains.plugins.groovy.debugger.fragments.GroovyCodeFragment;
|
||||
import org.jetbrains.plugins.groovy.lang.lexer.GroovyTokenTypes;
|
||||
import org.jetbrains.plugins.groovy.template.GroovyTemplateContextType;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Eugene.Kudelevsky
|
||||
*/
|
||||
public class GroovyStructuralSearchProfile extends StructuralSearchProfileBase {
|
||||
public static final String FILE_CONTEXT = "File";
|
||||
public static final String CLASS_CONTEXT = "Class";
|
||||
public static final PatternContext FILE_CONTEXT = new PatternContext("File", "Default");
|
||||
public static final PatternContext CLASS_CONTEXT = new PatternContext("Class", "Class Member");
|
||||
private static final List<PatternContext> PATTERN_CONTEXTS = ContainerUtil.immutableList(FILE_CONTEXT, CLASS_CONTEXT);
|
||||
|
||||
private static final TokenSet VARIABLE_DELIMITERS = TokenSet.create(GroovyTokenTypes.mCOMMA, GroovyTokenTypes.mSEMI);
|
||||
|
||||
@@ -31,8 +37,8 @@ public class GroovyStructuralSearchProfile extends StructuralSearchProfileBase {
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String[] getContextNames() {
|
||||
return new String[] {FILE_CONTEXT, CLASS_CONTEXT};
|
||||
public List<PatternContext> getPatternContexts() {
|
||||
return PATTERN_CONTEXTS;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -48,7 +54,7 @@ public class GroovyStructuralSearchProfile extends StructuralSearchProfileBase {
|
||||
}
|
||||
|
||||
@Override
|
||||
public PsiCodeFragment createCodeFragment(Project project, String text) {
|
||||
public PsiCodeFragment createCodeFragment(Project project, String text, String contextId) {
|
||||
return new GroovyCodeFragment(project, text);
|
||||
}
|
||||
|
||||
@@ -58,9 +64,10 @@ public class GroovyStructuralSearchProfile extends StructuralSearchProfileBase {
|
||||
return GroovyTemplateContextType.class;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String getContext(@NotNull String pattern, @Nullable Language language, String contextName) {
|
||||
return CLASS_CONTEXT.equals(contextName)
|
||||
public String getContext(@NotNull String pattern, @Nullable Language language, String contextId) {
|
||||
return CLASS_CONTEXT.getId().equals(contextId)
|
||||
? "class AAAAA { " + PATTERN_PLACEHOLDER + " }"
|
||||
: PATTERN_PLACEHOLDER;
|
||||
}
|
||||
|
||||
+2
-2
@@ -1,4 +1,4 @@
|
||||
// Copyright 2000-2017 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.structuralsearch;
|
||||
|
||||
import com.intellij.dupLocator.equivalence.EquivalenceDescriptorProvider;
|
||||
@@ -112,7 +112,7 @@ public class GroovyStructuralSearchTest extends StructuralSearchTestCase {
|
||||
doTest(s, "def $name$ = {\n" +
|
||||
" '_T+\n" +
|
||||
"}", 0, 0);
|
||||
final String old = options.getPatternContext();
|
||||
final PatternContext old = options.getPatternContext();
|
||||
try {
|
||||
options.setPatternContext(GroovyStructuralSearchProfile.CLASS_CONTEXT);
|
||||
doTest(s, "def $name$ = {\n" +
|
||||
|
||||
Reference in New Issue
Block a user