Skip to content

Commit b2904ba

Browse files
authored
Merge pull request #60 from jansorg/jansorg/path-antiquotations
Support antiquotations in paths
2 parents 3ebf1bd + 425bfd3 commit b2904ba

File tree

17 files changed

+350
-46
lines changed

17 files changed

+350
-46
lines changed

src/main/java/org/nixos/idea/lang/NixParserDefinition.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,14 @@ public SpaceRequirements spaceExistenceTypeBetweenTokens(ASTNode left, ASTNode r
7777
if (leftType == NixTypes.DOLLAR && rightType == NixTypes.LCURLY) {
7878
return SpaceRequirements.MUST_NOT;
7979
}
80+
else if (leftType == NixTypes.PATH_SEGMENT) {
81+
// path segment, antiquotation or PATH_END on the right
82+
return SpaceRequirements.MUST_NOT;
83+
}
84+
else if (rightType == NixTypes.PATH_END) {
85+
// path segment or antiquotation on the left
86+
return SpaceRequirements.MUST_NOT;
87+
}
8088
else if (NixTypeUtil.MIGHT_COLLAPSE_WITH_ID.contains(leftType) &&
8189
NixTypeUtil.MIGHT_COLLAPSE_WITH_ID.contains(rightType)) {
8290
return SpaceRequirements.MUST;

src/main/java/org/nixos/idea/lang/highlighter/NixSyntaxHighlighter.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,8 +66,7 @@ public class NixSyntaxHighlighter extends SyntaxHighlighterBase {
6666
// Literals
6767
entry(NixTypes.INT, NixTextAttributes.NUMBER),
6868
entry(NixTypes.FLOAT, NixTextAttributes.NUMBER),
69-
entry(NixTypes.PATH, NixTextAttributes.PATH),
70-
entry(NixTypes.HPATH, NixTextAttributes.PATH),
69+
entry(NixTypes.PATH_SEGMENT, NixTextAttributes.PATH),
7170
entry(NixTypes.SPATH, NixTextAttributes.PATH),
7271
entry(NixTypes.URI, NixTextAttributes.URI),
7372
// String literals

src/main/java/org/nixos/idea/psi/NixTypeUtil.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,9 @@ public final class NixTypeUtil {
2424
NixTypes.ID,
2525
NixTypes.INT,
2626
NixTypes.FLOAT,
27-
NixTypes.PATH,
28-
NixTypes.HPATH,
2927
NixTypes.SPATH,
28+
NixTypes.PATH_SEGMENT,
29+
NixTypes.PATH_END,
3030
NixTypes.URI));
3131

3232
private NixTypeUtil() {} // Cannot be instantiated

src/main/java/org/nixos/idea/psi/impl/NixParserUtil.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import com.intellij.lang.PsiBuilder;
44
import com.intellij.lang.parser.GeneratedParserUtilBase;
55
import com.intellij.openapi.util.Key;
6+
import com.intellij.psi.TokenType;
67
import org.jetbrains.annotations.NotNull;
78

89
public final class NixParserUtil extends GeneratedParserUtilBase {

src/main/lang/Nix.bnf

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,9 @@ expr_simple ::=
169169
| list
170170
| legacy_let
171171
identifier ::= ID
172-
literal ::= INT | FLOAT | PATH | HPATH | SPATH | URI
172+
literal ::= INT | FLOAT | URI | path
173+
;{ extends("path")=literal }
174+
path ::= SPATH | PATH_SEGMENT (PATH_SEGMENT | antiquotation)* PATH_END
173175
parens ::= LPAREN expr recover_parens RPAREN { pin=1 }
174176
set ::= [ REC ] LCURLY recover_set (bind recover_set)* RCURLY { pin=2 }
175177
list ::= LBRAC recover_list (expr_select recover_list)* RBRAC { pin=1 }

src/main/lang/Nix.flex

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -43,15 +43,17 @@ import static org.nixos.idea.psi.NixTypes.*;
4343
%function advance
4444
%type IElementType
4545
%unicode
46-
%state BLOCK STRING IND_STRING ANTIQUOTATION_START ANTIQUOTATION
46+
%state BLOCK STRING IND_STRING ANTIQUOTATION_START ANTIQUOTATION PATH
4747

4848
ANY=[^]
4949
ID=[a-zA-Z_][a-zA-Z0-9_'-]*
5050
INT=[0-9]+
5151
FLOAT=(([1-9][0-9]*\.[0-9]*)|(0?\.[0-9]+))([Ee][+-]?[0-9]+)?
52-
PATH=[a-zA-Z0-9._+-]*(\/[a-zA-Z0-9._+-]+)+\/?
53-
HPATH=\~(\/[a-zA-Z0-9._+-]+)+\/?
54-
SPATH=\<[a-zA-Z0-9._+-]+(\/[a-zA-Z0-9._+-]+)*\>
52+
PATH_CHAR=[a-zA-Z0-9\.\_\-\+]
53+
PATH={PATH_CHAR}*(\/{PATH_CHAR}+)+\/?
54+
PATH_SEG={PATH_CHAR}*\/
55+
HPATH_START=\~\/
56+
SPATH=\<{PATH_CHAR}+(\/{PATH_CHAR}+)*\>
5557
URI=[a-zA-Z][a-zA-Z0-9.+-]*\:[a-zA-Z0-9%/?:@&=+$,\-_.!~*']+
5658

5759
WHITE_SPACE=[\ \t\r\n]+
@@ -91,6 +93,16 @@ MCOMMENT=\/\*([^*]|\*[^\/])*\*\/
9193
"}" { popState(BLOCK); return RCURLY; }
9294
}
9395

96+
<PATH> {
97+
"$"/"{" { pushState(ANTIQUOTATION_START); return DOLLAR; }
98+
{PATH_SEG} { return PATH_SEGMENT; }
99+
{PATH_CHAR}+ { return PATH_SEGMENT; }
100+
// anything else, e.g. whitespace, stops lexing of a PATH
101+
// we're delegating back to the parent state
102+
// PATH_END is an empty-length token to signal the end of the path
103+
[^] { popState(PATH); yypushback(yylength()); return PATH_END; }
104+
}
105+
94106
<YYINITIAL, BLOCK, ANTIQUOTATION> {
95107
"if" { return IF; }
96108
"then" { return THEN; }
@@ -146,8 +158,10 @@ MCOMMENT=\/\*([^*]|\*[^\/])*\*\/
146158
{ID} { return ID; }
147159
{INT} { return INT; }
148160
{FLOAT} { return FLOAT; }
149-
{PATH} { return PATH; }
150-
{HPATH} { return HPATH; }
161+
"/" / "${" { pushState(PATH); return PATH_SEGMENT; }
162+
{PATH}
163+
| {PATH_SEG}
164+
| {HPATH_START} { pushState(PATH); return PATH_SEGMENT; }
151165
{SPATH} { return SPATH; }
152166
{URI} { return URI; }
153167

src/test/java/org/nixos/idea/lang/ParsingTest.java

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -145,10 +145,13 @@ public void testWith() {
145145

146146
@Override
147147
protected void tearDown() throws Exception {
148-
// Ensure that the parser does not generate errors even when the errors have
149-
// accidentally been added to the expected result.
150-
ensureNoErrorElements();
151-
super.tearDown();
148+
try {
149+
// Ensure that the parser does not generate errors even when the errors have
150+
// accidentally been added to the expected result.
151+
ensureNoErrorElements();
152+
} finally {
153+
super.tearDown();
154+
}
152155
}
153156

154157
@Override

src/test/java/org/nixos/idea/lang/highlighter/NixSyntaxHighlighterTest.java

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import com.intellij.openapi.editor.colors.TextAttributesKey;
44
import com.intellij.psi.TokenType;
55
import com.intellij.psi.tree.IElementType;
6+
import com.intellij.psi.tree.TokenSet;
67
import org.jetbrains.annotations.NotNull;
78
import org.junit.jupiter.api.Named;
89
import org.junit.jupiter.api.Test;
@@ -15,12 +16,12 @@
1516
import java.util.stream.IntStream;
1617
import java.util.stream.Stream;
1718

18-
import static org.junit.jupiter.api.Assertions.assertAll;
19-
import static org.junit.jupiter.api.Assertions.assertEquals;
20-
import static org.junit.jupiter.api.Assertions.assertNotEquals;
21-
import static org.junit.jupiter.api.Assertions.assertNotNull;
19+
import static java.util.function.Predicate.not;
20+
import static org.junit.jupiter.api.Assertions.*;
2221

2322
final class NixSyntaxHighlighterTest {
23+
private static final TokenSet EMPTY_LENGTH_TOKENS = TokenSet.create(NixTypes.PATH_END);
24+
2425
@Test
2526
void testAttributesKeysForUnknownTokenType() {
2627
TextAttributesKey[] tokenHighlights = new NixSyntaxHighlighter().getTokenHighlights(TokenType.CODE_FRAGMENT);
@@ -38,9 +39,10 @@ void testAttributesKeysForKnownTokenTypes(@NotNull IElementType tokenType) {
3839
() -> assertNotNull(tokenHighlights[index], String.format("tokenHighlights[%d]", index))));
3940
}
4041

41-
static @NotNull Stream<Named<IElementType>> testAttributesKeysForKnownTokenTypes() {
42+
static @NotNull Stream<Named<? extends IElementType>> testAttributesKeysForKnownTokenTypes() {
4243
return Stream.concat(
4344
Stream.of(Named.of("TokenType.BAD_CHARACTER", TokenType.BAD_CHARACTER)),
44-
ReflectionUtils.getPublicStaticFieldValues(NixTypes.class, NixTokenType.class));
45+
ReflectionUtils.getPublicStaticFieldValues(NixTypes.class, NixTokenType.class)
46+
).filter(not(named -> EMPTY_LENGTH_TOKENS.contains(named.getPayload())));
4547
}
4648
}

src/test/testData/ParsingTest/List.lexer.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@
22
WHITE_SPACE (' ')
33
INT ('123')
44
WHITE_SPACE (' ')
5-
PATH ('./foo.nix')
5+
PATH_SEGMENT ('./foo.nix')
6+
PATH_END ('')
67
WHITE_SPACE (' ')
78
STRING_OPEN ('"')
89
STR ('abc')

src/test/testData/ParsingTest/List.txt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@ Nix File(0,36)
55
NixLiteralImpl(LITERAL)(2,5)
66
PsiElement(INT)('123')(2,5)
77
PsiWhiteSpace(' ')(5,6)
8-
NixLiteralImpl(LITERAL)(6,15)
9-
PsiElement(PATH)('./foo.nix')(6,15)
8+
NixPathImpl(PATH)(6,15)
9+
PsiElement(PATH_SEGMENT)('./foo.nix')(6,15)
1010
PsiWhiteSpace(' ')(15,16)
1111
NixStdStringImpl(STD_STRING)(16,21)
1212
PsiElement(STRING_OPEN)('"')(16,17)
@@ -33,4 +33,4 @@ Nix File(0,36)
3333
PsiWhiteSpace(' ')(32,33)
3434
PsiElement(})('}')(33,34)
3535
PsiWhiteSpace(' ')(34,35)
36-
PsiElement(])(']')(35,36)
36+
PsiElement(])(']')(35,36)

0 commit comments

Comments
 (0)