regex: simpler intersection parsing to improve selection behaviour

This commit is contained in:
Bas Leijdekkers
2016-05-27 12:47:37 +02:00
parent f92b648970
commit 77de015f8d
3 changed files with 23 additions and 33 deletions
@@ -106,18 +106,18 @@ public class RegExpParser implements PsiParser {
* CLOSURE ::= GROUP QUANTIFIER
*/
private boolean parseAtom(PsiBuilder builder) {
PsiBuilder.Marker marker = parseGroup(builder);
final PsiBuilder.Marker marker = parseGroup(builder);
if (marker == null) {
return false;
}
marker = marker.precede();
final PsiBuilder.Marker marker2 = marker.precede();
if (parseQuantifier(builder)) {
marker.done(RegExpElementTypes.CLOSURE);
marker2.done(RegExpElementTypes.CLOSURE);
}
else {
marker.drop();
marker2.drop();
}
return true;
@@ -134,9 +134,9 @@ public class RegExpParser implements PsiParser {
if (builder.getTokenType() == RegExpTT.LBRACE) {
builder.advanceLexer();
boolean minOmitted = false;
if (builder.getTokenType() == RegExpTT.COMMA && myCapabilities.contains(RegExpCapability.OMIT_NUMBERS_IN_QUANTIFIERS)) {
minOmitted = true;
final boolean minOmitted = builder.getTokenType() == RegExpTT.COMMA &&
myCapabilities.contains(RegExpCapability.OMIT_NUMBERS_IN_QUANTIFIERS);
if (minOmitted) {
builder.advanceLexer();
}
else if (builder.getTokenType() != RegExpTT.NUMBER && myCapabilities.contains(RegExpCapability.DANGLING_METACHARACTERS)) {
@@ -229,20 +229,21 @@ public class RegExpParser implements PsiParser {
}
private boolean parseClassIntersection(PsiBuilder builder) {
PsiBuilder.Marker marker = builder.mark();
final PsiBuilder.Marker marker = builder.mark();
if (!parseClassdef(builder, false)) {
marker.drop();
return false;
}
if (RegExpTT.ANDAND != builder.getTokenType()) {
marker.drop();
return true;
}
while (RegExpTT.ANDAND == builder.getTokenType()) {
builder.advanceLexer();
parseClassdef(builder, true);
marker.done(RegExpElementTypes.INTERSECTION);
marker = marker.precede();
}
marker.drop();
marker.done(RegExpElementTypes.INTERSECTION);
return true;
}
@@ -280,12 +281,11 @@ public class RegExpParser implements PsiParser {
final PsiBuilder.Marker marker = builder.mark();
makeChar(builder);
IElementType t = builder.getTokenType();
if (t == RegExpTT.MINUS) {
if (builder.getTokenType() == RegExpTT.MINUS) {
final PsiBuilder.Marker m = builder.mark();
builder.advanceLexer();
t = builder.getTokenType();
final IElementType t = builder.getTokenType();
if (RegExpTT.CHARACTERS2.contains(t)) {
m.drop();
makeChar(builder);
@@ -16,15 +16,12 @@
package org.intellij.lang.regexp.psi;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
* Represents an intersection of class elements: [a-z&&[^cd]]
*/
public interface RegExpIntersection extends RegExpClassElement {
@NotNull
RegExpClassElement getLOperand();
@Nullable
RegExpClassElement getROperand();
@NotNull
RegExpClassElement[] getOperands();
}
@@ -16,32 +16,25 @@
package org.intellij.lang.regexp.psi.impl;
import com.intellij.lang.ASTNode;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.intellij.lang.regexp.psi.RegExpClassElement;
import org.intellij.lang.regexp.psi.RegExpElementVisitor;
import org.intellij.lang.regexp.psi.RegExpIntersection;
import org.intellij.lang.regexp.RegExpElementTypes;
import org.jetbrains.annotations.NotNull;
public class RegExpIntersectionImpl extends RegExpElementImpl implements RegExpIntersection {
public RegExpIntersectionImpl(ASTNode astNode) {
super(astNode);
}
@Override
public void accept(RegExpElementVisitor visitor) {
visitor.visitRegExpIntersection(this);
}
@Override
@NotNull
public RegExpClassElement getLOperand() {
final ASTNode[] nodes = getNode().getChildren(RegExpElementTypes.CLASS_ELEMENTS);
return (RegExpClassElement)nodes[0].getPsi();
}
@Nullable
public RegExpClassElement getROperand() {
final ASTNode[] nodes = getNode().getChildren(RegExpElementTypes.CLASS_ELEMENTS);
return nodes.length > 1 ? (RegExpClassElement)nodes[1].getPsi() : null;
public RegExpClassElement[] getOperands() {
return findChildrenByClass(RegExpClassElement.class);
}
}