Skip to content

Commit 090038d

Browse files
committed
Fix #102 Add parameter to 'experimental-identifier-usage' rules to flag some identifiers as non-experimental
1 parent 12e1a90 commit 090038d

File tree

16 files changed

+115
-14
lines changed

16 files changed

+115
-14
lines changed

css-checks/src/main/java/org/sonar/css/checks/common/ExperimentalIdentifierCheck.java

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,15 +19,22 @@
1919
*/
2020
package org.sonar.css.checks.common;
2121

22+
import com.google.common.annotations.VisibleForTesting;
2223
import org.sonar.check.Priority;
2324
import org.sonar.check.Rule;
25+
import org.sonar.check.RuleProperty;
26+
import org.sonar.css.checks.CheckList;
27+
import org.sonar.css.checks.CheckUtils;
2428
import org.sonar.css.checks.Tags;
2529
import org.sonar.plugins.css.api.tree.css.IdentifierTree;
2630
import org.sonar.plugins.css.api.tree.css.ValueTree;
2731
import org.sonar.plugins.css.api.visitors.DoubleDispatchVisitorCheck;
2832
import org.sonar.squidbridge.annotations.ActivatedByDefault;
2933
import org.sonar.squidbridge.annotations.SqaleConstantRemediation;
3034

35+
import java.util.regex.Pattern;
36+
import java.util.regex.PatternSyntaxException;
37+
3138
@Rule(
3239
key = "experimental-identifier-usage",
3340
name = "Experimental identifiers should not be used",
@@ -37,14 +44,43 @@
3744
@ActivatedByDefault
3845
public class ExperimentalIdentifierCheck extends DoubleDispatchVisitorCheck {
3946

47+
private static final String DEFAULT_IDENTIFIERS_TO_EXCLUDE = "";
48+
49+
@RuleProperty(
50+
key = "identifiersToExclude",
51+
description = "A regular expression to exclude identifiers from being considered as experimental. Example: \"gradient|flex.*\". See " + CheckUtils.LINK_TO_JAVA_REGEX_PATTERN_DOC + " for detailed regular expression syntax.",
52+
defaultValue = DEFAULT_IDENTIFIERS_TO_EXCLUDE)
53+
private String identifiersToExclude = DEFAULT_IDENTIFIERS_TO_EXCLUDE;
54+
4055
@Override
4156
public void visitValue(ValueTree tree) {
4257
tree.valueElementsOfType(IdentifierTree.class)
4358
.stream()
44-
.filter(IdentifierTree::isVendorPrefixed)
59+
.filter(i -> i.isVendorPrefixed() && !i.name().matches(identifiersToExclude))
4560
.forEach(i -> addPreciseIssue(i, "Remove this usage of the experimental \"" + i.text() + "\" identifier."));
4661

4762
super.visitValue(tree);
4863
}
4964

65+
@Override
66+
public void validateParameters() {
67+
try {
68+
Pattern.compile(identifiersToExclude);
69+
} catch (PatternSyntaxException exception) {
70+
throw new IllegalStateException(paramsErrorMessage(), exception);
71+
}
72+
}
73+
74+
@VisibleForTesting
75+
void setIdentifiersToExclude(String identifiersToExclude) {
76+
this.identifiersToExclude = identifiersToExclude;
77+
}
78+
79+
private String paramsErrorMessage() {
80+
return CheckUtils.paramsErrorMessage(
81+
this.getClass(),
82+
CheckList.CSS_REPOSITORY_KEY,
83+
"identifiersToExclude parameter \"" + identifiersToExclude + "\" is not a valid regular expression.");
84+
}
85+
5086
}

css-checks/src/test/java/org/sonar/css/checks/common/ExperimentalAtRuleCheckTest.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,5 +81,4 @@ private File getTestFile(String fileName) {
8181
return CheckTestUtils.getCommonTestFile("experimental-atrule-usage/" + fileName);
8282
}
8383

84-
8584
}

css-checks/src/test/java/org/sonar/css/checks/common/ExperimentalIdentifierCheckTest.java

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,39 @@
2323
import org.sonar.css.checks.CheckTestUtils;
2424
import org.sonar.css.checks.verifier.CssCheckVerifier;
2525

26+
import java.io.File;
27+
28+
import static org.fest.assertions.Assertions.assertThat;
29+
2630
public class ExperimentalIdentifierCheckTest {
2731

2832
@Test
2933
public void test() {
30-
CssCheckVerifier.verifyCssFile(new ExperimentalIdentifierCheck(), CheckTestUtils.getCommonTestFile("experimentalIdentifierUsage.css"));
34+
CssCheckVerifier.verifyCssFile(new ExperimentalIdentifierCheck(), getTestFile("experimentalIdentifierUsage.css"));
35+
}
36+
37+
@Test
38+
public void test_exclude_identifiers() {
39+
ExperimentalIdentifierCheck check = new ExperimentalIdentifierCheck();
40+
check.setIdentifiersToExclude("flex|defin.*");
41+
CssCheckVerifier.verifyCssFile(check, getTestFile("experimentalIdentifierUsageExcludeIdentifiers.css"));
3142
}
3243

44+
@Test
45+
public void should_throw_an_illegal_state_exception_as_the_identifiersToExclude_parameter_is_not_valid() {
46+
try {
47+
ExperimentalIdentifierCheck check = new ExperimentalIdentifierCheck();
48+
check.setIdentifiersToExclude("(");
49+
CssCheckVerifier.issuesOnCssFile(check, getTestFile("experimentalIdentifierUsage.css")).noMore();
50+
} catch (IllegalStateException e) {
51+
assertThat(e.getMessage()).isEqualTo("Check css:experimental-identifier-usage (Experimental identifiers should not be used): "
52+
+ "identifiersToExclude parameter \"(\" is not a valid regular expression.");
53+
}
54+
}
55+
56+
private File getTestFile(String fileName) {
57+
return CheckTestUtils.getCommonTestFile("experimental-identifier-usage/" + fileName);
58+
}
59+
60+
3361
}

css-checks/src/test/resources/checks/common/experimentalIdentifierUsage.css renamed to css-checks/src/test/resources/checks/common/experimental-identifier-usage/experimentalIdentifierUsage.css

File renamed without changes.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
.mybox {
2+
display: -moz-abc; /* Noncompliant ![sc=12;ec=20;el=+0]! !{Remove this usage of the experimental "-moz-abc" identifier.}! */
3+
display: -ms-definite;
4+
display: -moz-flex;
5+
}

css-frontend/src/main/java/org/sonar/css/tree/impl/css/IdentifierTreeImpl.java

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,12 +34,14 @@ public class IdentifierTreeImpl extends LiteralTreeImpl implements IdentifierTre
3434
private static final Pattern LESS_INTERPOLATED_VARIABLE = Pattern.compile("@\\{[\\w-_]+\\}");
3535
private static final Pattern SCSS_INTERPOLATED_VARIABLE = Pattern.compile("#\\{.+\\}");
3636
private final Vendor vendor;
37+
private final String name;
3738
private Scope scope;
3839
private Symbol symbol = null;
3940

4041
public IdentifierTreeImpl(SyntaxToken ident) {
4142
super(ident);
4243
this.vendor = setVendorPrefix();
44+
this.name = setName();
4345
}
4446

4547
@Override
@@ -82,6 +84,11 @@ public Vendor vendor() {
8284
return vendor;
8385
}
8486

87+
@Override
88+
public String name() {
89+
return name;
90+
}
91+
8592
private Vendor setVendorPrefix() {
8693
for (Vendor v : Vendor.values()) {
8794
if (text().toLowerCase(Locale.ENGLISH).startsWith(v.getPrefix())) {
@@ -91,6 +98,15 @@ private Vendor setVendorPrefix() {
9198
return null;
9299
}
93100

101+
private String setName() {
102+
for (Vendor v : Vendor.values()) {
103+
if (text().toLowerCase(Locale.ENGLISH).startsWith(v.getPrefix())) {
104+
return text().substring(v.getPrefix().length());
105+
}
106+
}
107+
return text();
108+
}
109+
94110
@Override
95111
public Scope scope() {
96112
return scope;

css-frontend/src/main/java/org/sonar/plugins/css/api/tree/css/IdentifierTree.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ public interface IdentifierTree extends LiteralTree {
3232
@Nullable
3333
Vendor vendor();
3434

35+
String name();
36+
3537
boolean isInterpolated();
3638

3739
boolean isLessInterpolated();

css-frontend/src/test/java/org/sonar/css/parser/css/IdentifierTreeTest.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,11 +46,13 @@ public void ident() {
4646
assertThat(tree.isVendorPrefixed()).isTrue();
4747
assertThat(tree.vendor()).isEqualTo(Vendor.MOZILLA);
4848
assertThat(tree.isLessInterpolated()).isFalse();
49+
assertThat(tree.name()).isEqualTo("box-sizing");
4950

5051
tree = checkParsed("_dunno-what");
5152
assertThat(tree.isVendorPrefixed()).isFalse();
5253
assertThat(tree.vendor()).isNull();
5354
assertThat(tree.isLessInterpolated()).isFalse();
55+
assertThat(tree.name()).isEqualTo("_dunno-what");
5456

5557
checkParsed("*");
5658
}

its/ruling/projects/custom/common/experimentalIdentifierUsage.css renamed to its/ruling/projects/custom/common/experimental-identifier-usage/experimentalIdentifierUsage.css

File renamed without changes.
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
.mybox {
2+
display: -moz-abc; /* Noncompliant ![sc=12;ec=20;el=+0]! !{Remove this usage of the experimental "-moz-abc" identifier.}! */
3+
display: -ms-definite;
4+
display: -moz-flex;
5+
}

0 commit comments

Comments
 (0)