mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
SSR: conditional visibility of constraints components
This commit is contained in:
+110
@@ -18,6 +18,7 @@ import com.intellij.openapi.fileTypes.StdFileTypes;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.impl.source.JavaDummyHolder;
|
||||
import com.intellij.psi.javadoc.PsiDocComment;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
@@ -831,4 +832,113 @@ public class JavaStructuralSearchProfile extends StructuralSearchProfile {
|
||||
|
||||
return offset;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isApplicableConstraint(String constraintName, @Nullable PsiElement variableNode, boolean completePattern, boolean target) {
|
||||
switch (constraintName) {
|
||||
case UIUtil.TEXT: return !completePattern;
|
||||
case UIUtil.TEXT_HIERARCHY:
|
||||
if (variableNode != null) {
|
||||
final PsiElement parent = variableNode.getParent();
|
||||
if (parent instanceof PsiJavaCodeReferenceElement && parent.getParent() instanceof PsiTypeElement ||
|
||||
parent instanceof PsiClass) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
case UIUtil.EXPECTED_TYPE:
|
||||
if (variableNode != null) {
|
||||
final PsiElement grandParent = variableNode.getParent().getParent();
|
||||
if (grandParent instanceof PsiExpressionStatement) {
|
||||
if (hasSemicolon(grandParent)) return false;
|
||||
}
|
||||
else if (grandParent instanceof PsiStatement) return false;
|
||||
}
|
||||
case UIUtil.TYPE:
|
||||
if (variableNode instanceof PsiExpressionStatement) {
|
||||
final PsiElement child = variableNode.getLastChild();
|
||||
if (child instanceof PsiErrorElement) {
|
||||
final PsiErrorElement errorElement = (PsiErrorElement)child;
|
||||
return "';' expected".equals(errorElement.getErrorDescription());
|
||||
}
|
||||
}
|
||||
return variableNode != null && variableNode.getParent() instanceof PsiExpression;
|
||||
case UIUtil.MINIMUM_ZERO:
|
||||
if (target) return false;
|
||||
return isApplicableCount(variableNode, false);
|
||||
case UIUtil.MAXIMUM_UNLIMITED:
|
||||
return isApplicableCount(variableNode, true);
|
||||
case UIUtil.REFERENCE:
|
||||
if (completePattern || variableNode == null) return false;
|
||||
if (variableNode instanceof PsiLiteralExpression && ((PsiLiteralExpression)variableNode).getValue() instanceof String) return true;
|
||||
final PsiElement parent = variableNode.getParent();
|
||||
return parent instanceof PsiReferenceExpression || parent instanceof PsiJavaCodeReferenceElement;
|
||||
default: return super.isApplicableConstraint(constraintName, variableNode, completePattern, target);
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean isApplicableCount(@Nullable PsiElement variableNode, boolean max) {
|
||||
if (variableNode != null) {
|
||||
final PsiElement parent = variableNode.getParent();
|
||||
if (max && parent instanceof PsiLocalVariable) {
|
||||
final PsiLocalVariable localVariable = (PsiLocalVariable)parent;
|
||||
if (localVariable instanceof PsiResourceVariable) return false;
|
||||
if (localVariable.getTypeElement().isInferredType()) return false;
|
||||
return true;
|
||||
}
|
||||
else if (max && parent instanceof PsiField) {
|
||||
return true;
|
||||
}
|
||||
if (parent instanceof PsiMember && !(parent instanceof PsiTypeParameter)) {
|
||||
final PsiMember member = (PsiMember)parent;
|
||||
final PsiClass aClass = member.getContainingClass();
|
||||
if (aClass == null) {
|
||||
return false;
|
||||
}
|
||||
final String name = aClass.getName();
|
||||
return name != null && !"_Dummy_".equals(name);
|
||||
}
|
||||
final PsiElement grandParent = parent.getParent();
|
||||
if (!max && parent instanceof PsiReferenceExpression && grandParent instanceof PsiReferenceExpression) {
|
||||
return true;
|
||||
}
|
||||
if (grandParent instanceof PsiAnnotation && !(grandParent.getParent().getNextSibling() instanceof PsiErrorElement)) {
|
||||
return true;
|
||||
}
|
||||
if (grandParent instanceof PsiExpressionStatement && hasSemicolon(grandParent)) {
|
||||
if (max) {
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
final PsiElement greatGrandParent = grandParent.getParent();
|
||||
return !(greatGrandParent instanceof PsiCodeBlock) || !(greatGrandParent.getParent() instanceof JavaDummyHolder);
|
||||
}
|
||||
}
|
||||
if (!max && grandParent instanceof PsiVariable &&
|
||||
PsiTreeUtil.isAncestor(((PsiVariable)grandParent).getInitializer(), variableNode, true)) {
|
||||
return true;
|
||||
}
|
||||
if (grandParent instanceof PsiReferenceList) {
|
||||
if (!max) return true;
|
||||
final PsiReferenceList referenceList = (PsiReferenceList)grandParent;
|
||||
final PsiElement greatGrandParent = referenceList.getParent();
|
||||
return !(greatGrandParent instanceof PsiClass) || ((PsiClass)greatGrandParent).getExtendsList() != referenceList;
|
||||
}
|
||||
if (grandParent instanceof PsiParameterList || grandParent instanceof PsiExpressionList ||
|
||||
grandParent instanceof PsiTypeParameterList || grandParent instanceof PsiResourceList) {
|
||||
return true;
|
||||
}
|
||||
if (grandParent instanceof PsiTypeElement && grandParent.getParent() instanceof PsiReferenceParameterList) return true;
|
||||
if (grandParent instanceof PsiPolyadicExpression && max) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static boolean hasSemicolon(PsiElement element) {
|
||||
PsiElement lastChild = element.getLastChild();
|
||||
while (lastChild instanceof PsiComment || lastChild instanceof PsiWhiteSpace) {
|
||||
lastChild = lastChild.getPrevSibling();
|
||||
}
|
||||
return PsiUtil.isJavaToken(lastChild, JavaTokenType.SEMICOLON);
|
||||
}
|
||||
}
|
||||
|
||||
+23
-1
@@ -211,7 +211,7 @@ public abstract class StructuralSearchProfile {
|
||||
int offset,
|
||||
ReplacementInfo replacementInfo) {
|
||||
if (info.getName().equals(match.getName())) {
|
||||
String replacementString = match.getMatchImage();
|
||||
final String replacementString;
|
||||
boolean removeSemicolon = false;
|
||||
if (match.hasChildren() && !match.isScopeMatch()) {
|
||||
// compound matches
|
||||
@@ -237,6 +237,7 @@ public abstract class StructuralSearchProfile {
|
||||
if (info.isStatementContext()) {
|
||||
removeSemicolon = match.getMatch() instanceof PsiComment;
|
||||
}
|
||||
replacementString = match.getMatchImage();
|
||||
}
|
||||
|
||||
offset = Replacer.insertSubstitution(result, offset, info, replacementString);
|
||||
@@ -280,4 +281,25 @@ public abstract class StructuralSearchProfile {
|
||||
public PsiElement getPresentableElement(PsiElement element) {
|
||||
return isIdentifier(element) ? element.getParent() : element;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 com.intellij.structuralsearch.plugin.ui.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) {
|
||||
switch (constraintName) {
|
||||
case UIUtil.TEXT:
|
||||
case UIUtil.MINIMUM_ZERO:
|
||||
if (target) return false;
|
||||
case UIUtil.MAXIMUM_UNLIMITED:
|
||||
case UIUtil.REFERENCE: return !completePattern;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
+14
@@ -13,10 +13,13 @@ import com.intellij.structuralsearch.impl.matcher.handlers.MatchingHandler;
|
||||
import com.intellij.structuralsearch.impl.matcher.handlers.SimpleHandler;
|
||||
import com.intellij.structuralsearch.impl.matcher.handlers.SubstitutionHandler;
|
||||
import com.intellij.structuralsearch.impl.matcher.strategies.MatchingStrategy;
|
||||
import com.intellij.util.SmartList;
|
||||
import com.intellij.util.containers.MultiMap;
|
||||
import gnu.trove.THashMap;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@@ -26,6 +29,7 @@ import java.util.Map;
|
||||
public abstract class CompiledPattern {
|
||||
public static final Key<Object> HANDLER_KEY = Key.create("ss.handler");
|
||||
private final Map<Object, MatchingHandler> handlers = new THashMap<>();
|
||||
private final MultiMap<String, PsiElement> variableNodes = MultiMap.createSmart();
|
||||
private SearchScope scope;
|
||||
private NodeIterator nodes;
|
||||
private MatchingStrategy strategy;
|
||||
@@ -159,4 +163,14 @@ public abstract class CompiledPattern {
|
||||
public String getAlternativeTextToMatch(PsiElement node, String previousText) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public List<PsiElement> getVariableNodes(@NotNull String name) {
|
||||
final Collection<PsiElement> elements = variableNodes.get(name);
|
||||
return elements instanceof List ? (List<PsiElement>)elements : new SmartList<>(elements);
|
||||
}
|
||||
|
||||
public void putVariableNode(@NotNull String name, @NotNull PsiElement node) {
|
||||
variableNodes.putValue(name, node);
|
||||
}
|
||||
}
|
||||
|
||||
+17
-12
@@ -23,6 +23,7 @@ import com.intellij.structuralsearch.impl.matcher.CompiledPattern;
|
||||
import com.intellij.structuralsearch.impl.matcher.MatcherImplUtil;
|
||||
import com.intellij.structuralsearch.impl.matcher.PatternTreeContext;
|
||||
import com.intellij.structuralsearch.impl.matcher.filters.LexicalNodesFilter;
|
||||
import com.intellij.structuralsearch.impl.matcher.handlers.DelegatingHandler;
|
||||
import com.intellij.structuralsearch.impl.matcher.handlers.MatchingHandler;
|
||||
import com.intellij.structuralsearch.impl.matcher.handlers.SubstitutionHandler;
|
||||
import com.intellij.structuralsearch.impl.matcher.predicates.*;
|
||||
@@ -111,10 +112,15 @@ public class PatternCompiler {
|
||||
|
||||
private static void checkForUnknownVariables(final CompiledPattern pattern, List<PsiElement> elements) {
|
||||
for (PsiElement element : elements) {
|
||||
pattern.putVariableNode(Configuration.CONTEXT_VAR_NAME, element);
|
||||
element.accept(new PsiRecursiveElementWalkingVisitor() {
|
||||
@Override
|
||||
public void visitElement(PsiElement element) {
|
||||
if (element.getUserData(CompiledPattern.HANDLER_KEY) != null) {
|
||||
final Object userData = element.getUserData(CompiledPattern.HANDLER_KEY);
|
||||
if (userData != null) {
|
||||
if (userData instanceof SubstitutionHandler) {
|
||||
pattern.putVariableNode(((SubstitutionHandler)userData).getName(), element);
|
||||
}
|
||||
return;
|
||||
}
|
||||
super.visitElement(element);
|
||||
@@ -131,10 +137,16 @@ public class PatternCompiler {
|
||||
}
|
||||
return;
|
||||
}
|
||||
final MatchingHandler handler = pattern.getHandler(pattern.getTypedVarString(element));
|
||||
MatchingHandler handler = pattern.getHandler(pattern.getTypedVarString(element));
|
||||
if (handler == null) {
|
||||
throw new MalformedPatternException();
|
||||
}
|
||||
if (handler instanceof DelegatingHandler) {
|
||||
handler = ((DelegatingHandler)handler).getDelegate();
|
||||
}
|
||||
if (handler instanceof SubstitutionHandler){
|
||||
pattern.putVariableNode(((SubstitutionHandler)handler).getName(), element);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -144,15 +156,9 @@ public class PatternCompiler {
|
||||
public static CompiledPattern getLastCompiledPattern(MatchOptions options) {
|
||||
synchronized (LOCK) {
|
||||
final CompiledPattern lastCompiledPattern = ourLastCompiledPattern == null ? null : ourLastCompiledPattern.get();
|
||||
if (lastCompiledPattern == null || !options.equals(ourLastMatchOptions)) {
|
||||
return null;
|
||||
}
|
||||
if (lastCompiledPattern.getScope() != null) {
|
||||
if (!options.getScope().equals(lastCompiledPattern.getScope())) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
else if (options.getScope() instanceof GlobalSearchScope) {
|
||||
if (lastCompiledPattern == null ||
|
||||
!options.equals(ourLastMatchOptions) ||
|
||||
options.getScope() instanceof GlobalSearchScope && options.getScope() != ourLastMatchOptions.getScope()) {
|
||||
return null;
|
||||
}
|
||||
return lastCompiledPattern;
|
||||
@@ -506,7 +512,6 @@ public class PatternCompiler {
|
||||
buf.append(text.substring(prevOffset));
|
||||
|
||||
PsiElement[] patternElements;
|
||||
|
||||
try {
|
||||
patternElements = MatcherImplUtil.createTreeFromText(buf.toString(), PatternTreeContext.Block, options.getFileType(),
|
||||
options.getDialect(), options.getPatternContext(), project, false);
|
||||
|
||||
+64
-72
@@ -19,6 +19,7 @@ import com.intellij.openapi.fileTypes.FileType;
|
||||
import com.intellij.openapi.fileTypes.FileTypeManager;
|
||||
import com.intellij.openapi.fileTypes.FileTypes;
|
||||
import com.intellij.openapi.fileTypes.StdFileTypes;
|
||||
import com.intellij.openapi.options.ConfigurationException;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.ui.ComponentWithBrowseButton;
|
||||
import com.intellij.openapi.ui.DialogWrapper;
|
||||
@@ -26,13 +27,13 @@ import com.intellij.openapi.ui.MessageType;
|
||||
import com.intellij.openapi.ui.popup.Balloon;
|
||||
import com.intellij.openapi.ui.popup.JBPopupFactory;
|
||||
import com.intellij.openapi.util.Disposer;
|
||||
import com.intellij.openapi.util.registry.Registry;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.openapi.wm.IdeFocusManager;
|
||||
import com.intellij.psi.PsiCodeFragment;
|
||||
import com.intellij.psi.PsiDocumentManager;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.psi.PsiFileFactory;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.structuralsearch.*;
|
||||
import com.intellij.structuralsearch.impl.matcher.CompiledPattern;
|
||||
import com.intellij.structuralsearch.impl.matcher.compiler.PatternCompiler;
|
||||
import com.intellij.structuralsearch.impl.matcher.predicates.ScriptLog;
|
||||
import com.intellij.structuralsearch.impl.matcher.predicates.ScriptSupport;
|
||||
import com.intellij.structuralsearch.plugin.replace.ReplaceOptions;
|
||||
@@ -64,6 +65,8 @@ import java.util.regex.PatternSyntaxException;
|
||||
*/
|
||||
class EditVarConstraintsDialog extends DialogWrapper {
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.structuralsearch.plugin.ui.EditVarConstraintsDialog");
|
||||
private final CompiledPattern myCompiledPattern;
|
||||
private final StructuralSearchProfile myProfile;
|
||||
|
||||
private IntegerField maxoccurs;
|
||||
private JCheckBox applyWithinTypeHierarchy;
|
||||
@@ -95,6 +98,8 @@ class EditVarConstraintsDialog extends DialogWrapper {
|
||||
private TextFieldWithAutoCompletionWithBrowseButton referenceTargetTextField;
|
||||
private JPanel referenceTargetConstraints;
|
||||
private JBCheckBox invertReferenceTarget;
|
||||
private JPanel expectedTypeConstraints;
|
||||
private JPanel scriptConstraints;
|
||||
|
||||
private final Project myProject;
|
||||
|
||||
@@ -103,6 +108,9 @@ class EditVarConstraintsDialog extends DialogWrapper {
|
||||
myProject = project;
|
||||
variables = _variables;
|
||||
myConfiguration = configuration;
|
||||
final MatchOptions matchOptions = myConfiguration.getMatchOptions();
|
||||
myCompiledPattern = PatternCompiler.getLastCompiledPattern(matchOptions);
|
||||
myProfile = StructuralSearchUtil.getProfileByFileType(fileType);
|
||||
|
||||
setTitle(SSRBundle.message("editvarcontraints.edit.variables"));
|
||||
|
||||
@@ -138,28 +146,6 @@ class EditVarConstraintsDialog extends DialogWrapper {
|
||||
variables.add(Configuration.CONTEXT_VAR_NAME);
|
||||
}
|
||||
|
||||
if (fileType == StdFileTypes.JAVA) {
|
||||
formalArgTypeWithinHierarchy.setEnabled(true);
|
||||
invertFormalArgType.setEnabled(true);
|
||||
formalArgType.setEnabled(true);
|
||||
|
||||
exprTypeWithinHierarchy.setEnabled(true);
|
||||
notExprType.setEnabled(true);
|
||||
regexprForExprType.setEnabled(true);
|
||||
|
||||
applyWithinTypeHierarchy.setEnabled(true);
|
||||
} else {
|
||||
formalArgTypeWithinHierarchy.setEnabled(false);
|
||||
invertFormalArgType.setEnabled(false);
|
||||
formalArgType.setEnabled(false);
|
||||
|
||||
exprTypeWithinHierarchy.setEnabled(false);
|
||||
notExprType.setEnabled(false);
|
||||
regexprForExprType.setEnabled(false);
|
||||
|
||||
applyWithinTypeHierarchy.setEnabled(false);
|
||||
}
|
||||
|
||||
parameterList.setModel(
|
||||
new AbstractListModel<String>() {
|
||||
@Override
|
||||
@@ -173,9 +159,7 @@ class EditVarConstraintsDialog extends DialogWrapper {
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
parameterList.setSelectionMode( ListSelectionModel.SINGLE_SELECTION );
|
||||
|
||||
parameterList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
|
||||
parameterList.getSelectionModel().addListSelectionListener(
|
||||
new ListSelectionListener() {
|
||||
boolean rollingBackSelection;
|
||||
@@ -199,7 +183,6 @@ class EditVarConstraintsDialog extends DialogWrapper {
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
parameterList.setCellRenderer(
|
||||
new DefaultListCellRenderer() {
|
||||
@Override
|
||||
@@ -217,7 +200,7 @@ class EditVarConstraintsDialog extends DialogWrapper {
|
||||
customScriptCode.getButton().addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(@NotNull final ActionEvent e) {
|
||||
final List<String> variableNames = ContainerUtil.newArrayList(myConfiguration.getMatchOptions().getVariableConstraintNames());
|
||||
final List<String> variableNames = ContainerUtil.newArrayList(matchOptions.getVariableConstraintNames());
|
||||
variableNames.add(ScriptLog.SCRIPT_LOG_VAR_NAME);
|
||||
final EditScriptDialog dialog = new EditScriptDialog(project, customScriptCode.getChildComponent().getText(), variableNames);
|
||||
dialog.show();
|
||||
@@ -231,7 +214,7 @@ class EditVarConstraintsDialog extends DialogWrapper {
|
||||
if (!variables.isEmpty()) {
|
||||
final String variableName = configuration.getCurrentVariableName();
|
||||
configuration.setCurrentVariableName(null);
|
||||
final int selectedIndex = variableName != null ? variables.indexOf(variableName) : 0;
|
||||
final int selectedIndex = variableName != null ? Math.max(0, variables.indexOf(variableName)) : 0;
|
||||
parameterList.setSelectedIndex(selectedIndex);
|
||||
}
|
||||
}
|
||||
@@ -337,15 +320,51 @@ class EditVarConstraintsDialog extends DialogWrapper {
|
||||
}
|
||||
|
||||
void copyValuesToUI(String varName) {
|
||||
if (varName == null) return;
|
||||
if (isReplacementVariable(varName)) {
|
||||
final ReplacementVariableDefinition definition =
|
||||
((ReplaceConfiguration)myConfiguration).getReplaceOptions().getVariableDefinition(stripReplacementVarDecoration(varName));
|
||||
|
||||
restoreScriptCode(definition);
|
||||
setSearchConstraintsVisible(false);
|
||||
textConstraintsPanel.setVisible(false);
|
||||
occurencePanel.setVisible(false);
|
||||
expressionConstraints.setVisible(false);
|
||||
partOfSearchResults.setVisible(false);
|
||||
containedInConstraints.setVisible(false);
|
||||
referenceTargetConstraints.setVisible(false);
|
||||
scriptConstraints.setVisible(true);
|
||||
return;
|
||||
} else {
|
||||
setSearchConstraintsVisible(true);
|
||||
final List<PsiElement> nodes = myCompiledPattern.getVariableNodes(varName);
|
||||
final PsiElement node = nodes.size() == 1 ? nodes.get(0) : null;
|
||||
final boolean completePattern = Configuration.CONTEXT_VAR_NAME.equals(varName);
|
||||
|
||||
final boolean text = myProfile.isApplicableConstraint(UIUtil.TEXT, node, completePattern, false);
|
||||
textConstraintsPanel.setVisible(text);
|
||||
applyWithinTypeHierarchy.setVisible(text && myProfile.isApplicableConstraint(UIUtil.TEXT_HIERARCHY, node, completePattern, false));
|
||||
final boolean minZero = myProfile.isApplicableConstraint(UIUtil.MINIMUM_ZERO, node, completePattern, false);
|
||||
final boolean maxUnlimited = myProfile.isApplicableConstraint(UIUtil.MAXIMUM_UNLIMITED, node, completePattern, false);
|
||||
if (minZero || maxUnlimited) {
|
||||
occurencePanel.setVisible(true);
|
||||
minoccurs.setMinValue(minZero ? 0 : 1);
|
||||
minoccurs.setDefaultValue(minZero ? 0 : 1);
|
||||
minoccurs.setDefaultValueText(minZero ? "0" : "1");
|
||||
maxoccurs.setMaxValue(maxUnlimited ? Integer.MAX_VALUE : 1);
|
||||
maxoccurs.setDefaultValue(maxUnlimited ? Integer.MAX_VALUE : 1);
|
||||
maxoccurs.setDefaultValueText(maxUnlimited ? SSRBundle.message("editvarcontraints.unlimited") : "1");
|
||||
}
|
||||
else {
|
||||
occurencePanel.setVisible(false);
|
||||
}
|
||||
final boolean typeComponent = myProfile.isApplicableConstraint(UIUtil.TYPE, node, completePattern, false);
|
||||
expressionConstraints.setVisible(typeComponent);
|
||||
expectedTypeConstraints.setVisible(typeComponent && myProfile.isApplicableConstraint(UIUtil.EXPECTED_TYPE, node, completePattern,
|
||||
false));
|
||||
referenceTargetConstraints.setVisible(myProfile.isApplicableConstraint(UIUtil.REFERENCE, node, completePattern, false));
|
||||
containedInConstraints.setVisible(completePattern);
|
||||
scriptConstraints.setVisible(Registry.is("ssr.enable.script.constraint.on.all.variables") || completePattern);
|
||||
|
||||
partOfSearchResults.setEnabled(!completePattern);
|
||||
}
|
||||
|
||||
final MatchOptions matchOptions = myConfiguration.getMatchOptions();
|
||||
@@ -406,22 +425,6 @@ class EditVarConstraintsDialog extends DialogWrapper {
|
||||
referenceTargetTextField.setText(StringUtil.unquoteString(varInfo.getReferenceConstraint()));
|
||||
invertReferenceTarget.setSelected(varInfo.isInvertReference());
|
||||
}
|
||||
|
||||
final boolean contextVar = Configuration.CONTEXT_VAR_NAME.equals(varName);
|
||||
containedInConstraints.setVisible(contextVar);
|
||||
textConstraintsPanel.setVisible(!contextVar);
|
||||
partOfSearchResults.setEnabled(!contextVar);
|
||||
occurencePanel.setVisible(!contextVar);
|
||||
referenceTargetConstraints.setVisible(!contextVar);
|
||||
}
|
||||
|
||||
private void setSearchConstraintsVisible(boolean b) {
|
||||
textConstraintsPanel.setVisible(b);
|
||||
occurencePanel.setVisible(b);
|
||||
expressionConstraints.setVisible(b);
|
||||
partOfSearchResults.setVisible(b);
|
||||
containedInConstraints.setVisible(b);
|
||||
referenceTargetConstraints.setVisible(b);
|
||||
}
|
||||
|
||||
private void restoreScriptCode(NamedScriptableDefinition varInfo) {
|
||||
@@ -471,30 +474,19 @@ class EditVarConstraintsDialog extends DialogWrapper {
|
||||
}
|
||||
|
||||
private boolean validateCounts() {
|
||||
final int minValue;
|
||||
final String minoccursText = minoccurs.getText();
|
||||
if (!minoccursText.isEmpty()) {
|
||||
try {
|
||||
minValue = Integer.parseInt(minoccursText);
|
||||
if (minValue < 0) throw new NumberFormatException();
|
||||
}
|
||||
catch (NumberFormatException e) {
|
||||
return showError(minoccurs, SSRBundle.message("invalid.occurence.count"));
|
||||
}
|
||||
} else {
|
||||
minValue = 0;
|
||||
try {
|
||||
minoccurs.validateContent();
|
||||
}
|
||||
|
||||
final String maxoccursText = maxoccurs.getText();
|
||||
if (!maxoccursText.isEmpty()) {
|
||||
try {
|
||||
if (Integer.parseInt(maxoccursText) < minValue) throw new NumberFormatException();
|
||||
}
|
||||
catch (NumberFormatException e) {
|
||||
return showError(maxoccurs, SSRBundle.message("invalid.occurence.count"));
|
||||
}
|
||||
catch (ConfigurationException e) {
|
||||
return showError(minoccurs, SSRBundle.message("invalid.occurence.count"));
|
||||
}
|
||||
return true;
|
||||
try {
|
||||
maxoccurs.validateContent();
|
||||
}
|
||||
catch (ConfigurationException e) {
|
||||
return showError(maxoccurs, SSRBundle.message("invalid.occurence.count"));
|
||||
}
|
||||
return maxoccurs.getValue() >= minoccurs.getValue() || showError(maxoccurs, SSRBundle.message("invalid.occurence.count"));
|
||||
}
|
||||
|
||||
private boolean showError(JComponent component, String message) {
|
||||
|
||||
+12
-2
@@ -38,6 +38,7 @@ import com.intellij.psi.codeStyle.CodeStyleManager;
|
||||
import com.intellij.psi.search.GlobalSearchScope;
|
||||
import com.intellij.psi.search.SearchScope;
|
||||
import com.intellij.structuralsearch.*;
|
||||
import com.intellij.structuralsearch.impl.matcher.compiler.PatternCompiler;
|
||||
import com.intellij.structuralsearch.plugin.StructuralSearchPlugin;
|
||||
import com.intellij.ui.ComboboxSpeedSearch;
|
||||
import com.intellij.ui.IdeBorderFactory;
|
||||
@@ -94,6 +95,7 @@ public class SearchDialog extends DialogWrapper {
|
||||
private String mySavedEditorText;
|
||||
private JPanel myContentPanel;
|
||||
private JComponent myEditorPanel;
|
||||
private JButton myEditVariablesButton;
|
||||
|
||||
public SearchDialog(SearchContext searchContext) {
|
||||
this(searchContext, true, true);
|
||||
@@ -168,7 +170,10 @@ public class SearchDialog extends DialogWrapper {
|
||||
myAlarm.addRequest(() -> {
|
||||
try {
|
||||
final boolean valid = isValid();
|
||||
ApplicationManager.getApplication().invokeLater(() -> getOKAction().setEnabled(valid));
|
||||
ApplicationManager.getApplication().invokeLater(() -> {
|
||||
myEditVariablesButton.setEnabled(PatternCompiler.getLastCompiledPattern(myConfiguration.getMatchOptions()) != null);
|
||||
getOKAction().setEnabled(valid);
|
||||
});
|
||||
}
|
||||
catch (ProcessCanceledException e) {
|
||||
throw e;
|
||||
@@ -523,7 +528,7 @@ public class SearchDialog extends DialogWrapper {
|
||||
panel.add(Box.createHorizontalStrut(8));
|
||||
|
||||
panel.add(
|
||||
createJButtonForAction(
|
||||
myEditVariablesButton = createJButtonForAction(
|
||||
new AbstractAction() {
|
||||
{
|
||||
putValue(NAME, SSRBundle.message("edit.variables.button"));
|
||||
@@ -531,6 +536,10 @@ public class SearchDialog extends DialogWrapper {
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
if (PatternCompiler.getLastCompiledPattern(myConfiguration.getMatchOptions()) == null) {
|
||||
myEditVariablesButton.setEnabled(false);
|
||||
return;
|
||||
}
|
||||
new EditVarConstraintsDialog(
|
||||
searchContext.getProject(),
|
||||
myConfiguration,
|
||||
@@ -561,6 +570,7 @@ public class SearchDialog extends DialogWrapper {
|
||||
Configuration[] configurations = dialog.getSelectedConfigurations();
|
||||
if (configurations.length == 1) {
|
||||
setSearchPattern(configurations[0]);
|
||||
initiateValidation();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,6 +46,14 @@ public class UIUtil {
|
||||
public static final NotificationGroup SSR_NOTIFICATION_GROUP =
|
||||
NotificationGroup.toolWindowGroup(SSRBundle.message("structural.search.title"), ToolWindowId.FIND);
|
||||
|
||||
@NonNls public static final String TEXT = "TEXT";
|
||||
@NonNls public static final String TEXT_HIERARCHY = "TEXT HIERARCHY";
|
||||
@NonNls public static final String REFERENCE = "REFERENCE";
|
||||
@NonNls public static final String TYPE = "TYPE";
|
||||
@NonNls public static final String EXPECTED_TYPE = "EXPECTED TYPE";
|
||||
@NonNls public static final String MINIMUM_ZERO = "MINIMUM ZERO";
|
||||
@NonNls public static final String MAXIMUM_UNLIMITED = "MAXIMUM UNLIMITED";
|
||||
|
||||
@NotNull
|
||||
public static Editor createEditor(Document doc, final Project project, boolean editable, @Nullable TemplateContextType contextType) {
|
||||
return createEditor(doc, project, editable, false, contextType);
|
||||
|
||||
+50
-40
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="com.intellij.structuralsearch.plugin.ui.EditVarConstraintsDialog">
|
||||
<grid id="53af4" binding="mainForm" layout-manager="GridLayoutManager" row-count="9" column-count="3" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
|
||||
<grid id="53af4" binding="mainForm" layout-manager="GridLayoutManager" row-count="9" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
|
||||
<margin top="0" left="0" bottom="0" right="0"/>
|
||||
<constraints>
|
||||
<xy x="24" y="82" width="889" height="760"/>
|
||||
@@ -36,7 +36,7 @@
|
||||
<grid id="4cae8" binding="textConstraintsPanel" layout-manager="GridLayoutManager" row-count="2" column-count="3" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
|
||||
<margin top="0" left="0" bottom="0" right="0"/>
|
||||
<constraints>
|
||||
<grid row="1" column="1" row-span="1" col-span="2" vsize-policy="0" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
|
||||
<grid row="1" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="7" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties/>
|
||||
<clientProperties>
|
||||
@@ -86,10 +86,10 @@
|
||||
</component>
|
||||
</children>
|
||||
</grid>
|
||||
<grid id="bb81f" binding="expressionConstraints" layout-manager="GridLayoutManager" row-count="4" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
|
||||
<grid id="bb81f" binding="expressionConstraints" layout-manager="GridLayoutManager" row-count="3" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
|
||||
<margin top="0" left="0" bottom="0" right="0"/>
|
||||
<constraints>
|
||||
<grid row="5" column="1" row-span="1" col-span="2" vsize-policy="0" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
|
||||
<grid row="5" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="7" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties/>
|
||||
<clientProperties>
|
||||
@@ -129,43 +129,53 @@
|
||||
<text resource-bundle="messages/SSRBundle" key="editvarcontraints.text.regular.expression.for.java.expression.type"/>
|
||||
</properties>
|
||||
</component>
|
||||
<component id="a97fa" class="javax.swing.JLabel">
|
||||
<grid id="1650b" binding="expectedTypeConstraints" layout-manager="GridLayoutManager" row-count="2" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
|
||||
<margin top="0" left="0" bottom="0" right="0"/>
|
||||
<constraints>
|
||||
<grid row="2" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<text resource-bundle="messages/SSRBundle" key="editvarcontraints.text.regular.expression.for.formal.argument.type.of.the.method"/>
|
||||
</properties>
|
||||
</component>
|
||||
<component id="d02c2" class="com.intellij.ui.EditorTextField" binding="formalArgType" custom-create="true">
|
||||
<constraints>
|
||||
<grid row="2" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="6" anchor="8" fill="1" indent="0" use-parent-layout="false">
|
||||
<preferred-size width="150" height="-1"/>
|
||||
</grid>
|
||||
<grid row="2" column="0" row-span="1" col-span="2" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="true"/>
|
||||
</constraints>
|
||||
<properties/>
|
||||
</component>
|
||||
<component id="bc6d0" class="javax.swing.JCheckBox" binding="invertFormalArgType">
|
||||
<constraints>
|
||||
<grid row="3" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<text resource-bundle="messages/SSRBundle" key="editvarcontraints.invert.condition"/>
|
||||
</properties>
|
||||
</component>
|
||||
<component id="2b0ea" class="javax.swing.JCheckBox" binding="formalArgTypeWithinHierarchy">
|
||||
<constraints>
|
||||
<grid row="3" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<text resource-bundle="messages/SSRBundle" key="editvarcontraints.apply.constraint.within.type.hierarchy"/>
|
||||
</properties>
|
||||
</component>
|
||||
<border type="none"/>
|
||||
<children>
|
||||
<component id="a97fa" class="javax.swing.JLabel">
|
||||
<constraints>
|
||||
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<text resource-bundle="messages/SSRBundle" key="editvarcontraints.text.regular.expression.for.formal.argument.type.of.the.method"/>
|
||||
</properties>
|
||||
</component>
|
||||
<component id="d02c2" class="com.intellij.ui.EditorTextField" binding="formalArgType" custom-create="true">
|
||||
<constraints>
|
||||
<grid row="0" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="6" anchor="8" fill="1" indent="0" use-parent-layout="false">
|
||||
<preferred-size width="150" height="-1"/>
|
||||
</grid>
|
||||
</constraints>
|
||||
<properties/>
|
||||
</component>
|
||||
<component id="2b0ea" class="javax.swing.JCheckBox" binding="formalArgTypeWithinHierarchy">
|
||||
<constraints>
|
||||
<grid row="1" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<text resource-bundle="messages/SSRBundle" key="editvarcontraints.apply.constraint.within.type.hierarchy"/>
|
||||
</properties>
|
||||
</component>
|
||||
<component id="bc6d0" class="javax.swing.JCheckBox" binding="invertFormalArgType">
|
||||
<constraints>
|
||||
<grid row="1" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<text resource-bundle="messages/SSRBundle" key="editvarcontraints.invert.condition"/>
|
||||
</properties>
|
||||
</component>
|
||||
</children>
|
||||
</grid>
|
||||
</children>
|
||||
</grid>
|
||||
<component id="9a3a8" class="javax.swing.JCheckBox" binding="partOfSearchResults">
|
||||
<constraints>
|
||||
<grid row="7" column="1" row-span="1" col-span="2" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
|
||||
<grid row="7" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<text resource-bundle="messages/SSRBundle" key="editvarcontraints.this.variable.is.target.of.the.search"/>
|
||||
@@ -173,13 +183,13 @@
|
||||
</component>
|
||||
<vspacer id="d06dd">
|
||||
<constraints>
|
||||
<grid row="8" column="1" row-span="1" col-span="2" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
|
||||
<grid row="8" column="1" row-span="1" col-span="1" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
</vspacer>
|
||||
<grid id="d8664" binding="occurencePanel" layout-manager="GridLayoutManager" row-count="1" column-count="4" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
|
||||
<margin top="0" left="0" bottom="0" right="0"/>
|
||||
<constraints>
|
||||
<grid row="3" column="1" row-span="1" col-span="2" vsize-policy="0" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
|
||||
<grid row="3" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="7" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties/>
|
||||
<clientProperties>
|
||||
@@ -233,7 +243,7 @@
|
||||
<grid id="463bd" binding="containedInConstraints" layout-manager="GridLayoutManager" row-count="2" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
|
||||
<margin top="0" left="0" bottom="0" right="0"/>
|
||||
<constraints>
|
||||
<grid row="2" column="1" row-span="1" col-span="2" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
|
||||
<grid row="2" column="1" row-span="1" col-span="1" vsize-policy="3" hsize-policy="7" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties/>
|
||||
<clientProperties>
|
||||
@@ -267,11 +277,11 @@
|
||||
</grid>
|
||||
<component id="ce461" class="javax.swing.JLabel" binding="myRegExHelpLabel" custom-create="true">
|
||||
<constraints>
|
||||
<grid row="0" column="1" row-span="1" col-span="2" vsize-policy="0" hsize-policy="0" anchor="4" fill="0" indent="0" use-parent-layout="false"/>
|
||||
<grid row="0" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="4" fill="0" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties/>
|
||||
</component>
|
||||
<grid id="964fd" layout-manager="GridLayoutManager" row-count="1" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
|
||||
<grid id="964fd" binding="scriptConstraints" layout-manager="GridLayoutManager" row-count="1" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
|
||||
<margin top="0" left="0" bottom="0" right="0"/>
|
||||
<constraints>
|
||||
<grid row="6" column="1" row-span="1" col-span="1" vsize-policy="3" hsize-policy="7" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
|
||||
@@ -303,7 +313,7 @@
|
||||
<grid id="3b230" binding="referenceTargetConstraints" layout-manager="GridLayoutManager" row-count="2" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
|
||||
<margin top="0" left="0" bottom="0" right="0"/>
|
||||
<constraints>
|
||||
<grid row="4" column="1" row-span="1" col-span="2" vsize-policy="3" hsize-policy="7" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
|
||||
<grid row="4" column="1" row-span="1" col-span="1" vsize-policy="3" hsize-policy="7" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties/>
|
||||
<clientProperties>
|
||||
|
||||
@@ -1479,6 +1479,9 @@ ESLint.Language.Service.full.log.description=ESLint: include source code fragmen
|
||||
goto.action.skip.tophits.and.options=false
|
||||
goto.action.skip.tophits.and.options.description=Skip top hits and options in go to action
|
||||
|
||||
ssr.enable.script.constraint.on.all.variables=true
|
||||
ssr.enable.script.constraint.on.all.variables.description=Restores ability to have script constraints on all variables instead of only on Complete Match and Replacement variables
|
||||
|
||||
dsm.show.cycle.count.in.tooltip=false
|
||||
dsm.show.cycle.count.in.tooltip.description=Shows number of cycles found in the tooltip of the Toggle Cycles toolbar button after some calculation time
|
||||
jdk.regex.soe.workaround=true
|
||||
|
||||
Reference in New Issue
Block a user