diff --git a/css-frontend/src/main/java/org/sonar/css/parser/LexicalGrammar.java b/css-frontend/src/main/java/org/sonar/css/parser/LexicalGrammar.java index 775d8e11..ca201d09 100644 --- a/css-frontend/src/main/java/org/sonar/css/parser/LexicalGrammar.java +++ b/css-frontend/src/main/java/org/sonar/css/parser/LexicalGrammar.java @@ -299,6 +299,8 @@ public enum LexicalGrammar implements GrammarRuleKey { SCSS_MULTILINE_STRING, SCSS_MULTILINE_STRING_LITERAL, + SCSS_IDENT, + /* Less */ LESS_VARIABLE_DECLARATION, LESS_VARIABLE_DECLARATION_AS_PARAMETER, @@ -623,10 +625,17 @@ private static void scss(LexerlessGrammarBuilder b) { b.rule(SCSS_AT_ROOT_WITH).is(SPACING, b.token(GenericTokenType.LITERAL, "with")); b.rule(SCSS_AT_ROOT_WITHOUT).is(SPACING, b.token(GenericTokenType.LITERAL, "without")); + b.rule(SCSS_IDENT).is( + b.firstOf( + b.regexp("(?i)(progid:DXImageTransform\\.Microsoft\\.[a-z]+)"), + b.sequence(_NMSTART, b.zeroOrMore(_NMCHAR)), + b.oneOrMore(_NMCHAR))) + .skip(); + b.rule(SCSS_IDENT_INTERPOLATED_IDENTIFIER_NO_WS).is( b.token(GenericTokenType.LITERAL, b.sequence( - b.optional(IDENT_IDENTIFIER_NO_WS), + b.optional(SCSS_IDENT), b.regexp("#\\{[^\\n\\r\\f\\}]*\\}"), b.zeroOrMore( b.firstOf( diff --git a/css-frontend/src/test/java/org/sonar/css/parser/scss/ClassSelectorTreeTest.java b/css-frontend/src/test/java/org/sonar/css/parser/scss/ClassSelectorTreeTest.java index 4f2780a6..1246d03c 100644 --- a/css-frontend/src/test/java/org/sonar/css/parser/scss/ClassSelectorTreeTest.java +++ b/css-frontend/src/test/java/org/sonar/css/parser/scss/ClassSelectorTreeTest.java @@ -41,6 +41,8 @@ public void classSelector() { checkParsed(".abc#{$class}", "abc#{$class}", true); checkParsed(".abc#{$class}#{$class1}def", "abc#{$class}#{$class1}def", true); checkParsed(".abc#{$class}e#{$class1}def", "abc#{$class}e#{$class1}def", true); + checkParsed(".-abc#{$class}e#{$class1}def", "-abc#{$class}e#{$class1}def", true); + checkParsed(".--abc#{$class}e#{$class1}def", "--abc#{$class}e#{$class1}def", true); } @Test diff --git a/css-frontend/src/test/java/org/sonar/css/parser/scss/IdSelectorTreeTest.java b/css-frontend/src/test/java/org/sonar/css/parser/scss/IdSelectorTreeTest.java index d72da220..68728997 100644 --- a/css-frontend/src/test/java/org/sonar/css/parser/scss/IdSelectorTreeTest.java +++ b/css-frontend/src/test/java/org/sonar/css/parser/scss/IdSelectorTreeTest.java @@ -35,6 +35,8 @@ public IdSelectorTreeTest() { public void idSelector() { checkParsed("#id", "id", false); checkParsed("#id#{$abc}-def", "id#{$abc}-def", true); + checkParsed("#-id#{$abc}-def", "-id#{$abc}-def", true); + checkParsed("#--id#{$abc}-def", "--id#{$abc}-def", true); } @Test diff --git a/css-frontend/src/test/java/org/sonar/css/parser/scss/ScssInterpolatedIdentifierNoWSTreeTest.java b/css-frontend/src/test/java/org/sonar/css/parser/scss/ScssInterpolatedIdentifierNoWSTreeTest.java index ac60579b..745d2202 100644 --- a/css-frontend/src/test/java/org/sonar/css/parser/scss/ScssInterpolatedIdentifierNoWSTreeTest.java +++ b/css-frontend/src/test/java/org/sonar/css/parser/scss/ScssInterpolatedIdentifierNoWSTreeTest.java @@ -40,6 +40,7 @@ public void scssInterpolatedIdentifierNoWS() { checkParsed("abc#{$class}"); checkParsed("abc#{$class}#{$class1}def"); checkParsed("-moz-abc#{$class}e#{$class1}def"); + checkParsed("--abc#{$class}e#{$class1}def"); } @Test diff --git a/css-frontend/src/test/java/org/sonar/css/parser/scss/ScssInterpolatedIdentifierTreeTest.java b/css-frontend/src/test/java/org/sonar/css/parser/scss/ScssInterpolatedIdentifierTreeTest.java index 0c0d9ae9..15b79fbd 100644 --- a/css-frontend/src/test/java/org/sonar/css/parser/scss/ScssInterpolatedIdentifierTreeTest.java +++ b/css-frontend/src/test/java/org/sonar/css/parser/scss/ScssInterpolatedIdentifierTreeTest.java @@ -38,6 +38,8 @@ public void scssInterpolatedIdentifier() { checkParsed(" -moz-abc#{ $abc * 2 + 3}e#{$class1}def", "-moz-abc#{ $abc * 2 + 3}e#{$class1}def"); checkParsed("#{ 2 * 3 + 5 + $abc}", "#{ 2 * 3 + 5 + $abc}"); checkParsed("abc#{ 2 * 3 + 5 + $abc}def", "abc#{ 2 * 3 + 5 + $abc}def"); + checkParsed("-abc#{ 2 * 3 + 5 + $abc}def", "-abc#{ 2 * 3 + 5 + $abc}def"); + checkParsed("--abc#{ 2 * 3 + 5 + $abc}def", "--abc#{ 2 * 3 + 5 + $abc}def"); } @Test diff --git a/css-frontend/src/test/java/org/sonar/css/parser/scss/ScssMixinTreeTest.java b/css-frontend/src/test/java/org/sonar/css/parser/scss/ScssMixinTreeTest.java index d0b4cabe..163b22ff 100644 --- a/css-frontend/src/test/java/org/sonar/css/parser/scss/ScssMixinTreeTest.java +++ b/css-frontend/src/test/java/org/sonar/css/parser/scss/ScssMixinTreeTest.java @@ -95,6 +95,8 @@ public void scssMixin() { assertThat(tree.block().propertyDeclarations()).hasSize(2); assertThat(tree.block().rulesets()).hasSize(2); assertThat(tree.block().scssMixinIncludes()).hasSize(2); + + checkParsed("@mixin view-mixin($key) { &-#{$key}-view { color: red; } }"); } @Test