Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

V2 Annotation #37

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

import com.salesforce.omakase.ast.Rule;
import com.salesforce.slds.shared.models.core.Style;
import com.salesforce.slds.shared.models.locations.Range;
import org.apache.commons.lang3.builder.ToStringBuilder;

import static org.apache.commons.lang3.builder.ToStringStyle.JSON_STYLE;
Expand All @@ -18,6 +19,7 @@ public class Annotation {
private AnnotationType type;
private Style style;
private Rule rule;
private Range range;

public AnnotationScope getScope() {
return scope;
Expand Down Expand Up @@ -51,6 +53,13 @@ public void setStyle(Style style) {
this.style = style;
}

public Range getRange() {
return range;
}

public void setRange(Range range) {
this.range = range;
}

public static AnnotationBuilder builder() {
return new AnnotationBuilder();
Expand All @@ -61,6 +70,7 @@ public static class AnnotationBuilder {
private AnnotationType type;
private Style style;
private Rule rule;
private Range range;

public AnnotationBuilder scope(AnnotationScope scope) {
this.scope = scope;
Expand All @@ -77,6 +87,11 @@ public AnnotationBuilder style(Style style) {
return this;
}

public AnnotationBuilder range(Range range) {
this.range = range;
return this;
}

public AnnotationBuilder rule(Rule rule) {
this.rule = rule;
return this;
Expand All @@ -88,6 +103,7 @@ public Annotation build() {
result.setType(type);
result.setRule(rule);
result.setStyle(style);
result.setRange(range);

return result;
}
Expand All @@ -100,6 +116,7 @@ public String toString() {
.append("type", type)
.append("rule", rule)
.append("style", style)
.append("range", range)
.toString();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ public enum ContextKey {
UTILITY_CLASS,
DESIGN_TOKEN,
SLDS_MOBILE_VALIDATION,
V2_ANNOTATION;
HIDE_INTERNAL_TOKENS;

public static Optional<ContextKey> get(String name) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@

package com.salesforce.slds.shared.models.core;

import com.google.common.collect.Lists;
import com.salesforce.slds.shared.models.annotations.Annotation;
import com.salesforce.slds.shared.models.annotations.AnnotationScope;
import com.salesforce.slds.shared.models.annotations.AnnotationType;
import com.salesforce.slds.shared.models.locations.Location;
import com.salesforce.slds.shared.models.locations.Range;
Expand All @@ -33,6 +35,8 @@ public enum EntityType {LWC, AURA, OTHER}
private String componentName;
private EntityType entityType;

private List<Range> recommendationSuppressionRanges;

private Entry(
List<Input> inputs, String path, List<String> rawContent,
EntityType entityType, String componentName) {
Expand Down Expand Up @@ -88,11 +92,11 @@ public boolean hasAnnotations() {
}

public List<Annotation> getAnnotations() {
return inputs.stream().filter(input -> input.getType() == Input.Type.STYLE)
return inputs != null ? inputs.stream().filter(input -> input.getType() == Input.Type.STYLE)
.filter(input -> input instanceof RuleSet)
.map(Input::asRuleSet)
.map(RuleSet::getAnnotations)
.flatMap(List::stream).collect(Collectors.toList());
.flatMap(List::stream).collect(Collectors.toList()) : Lists.newArrayList();
}

/*
Expand Down Expand Up @@ -122,7 +126,11 @@ public List<Annotation> getAnnotations() {
* sldsValidatorIgnoreNextLine (i.e 14) should also be exempt from validation rules.
*/
public List<Range> getRecommendationSuppressionRanges() {
ArrayList<Range> lintingIgnoreRanges = new ArrayList<Range>();
if (this.recommendationSuppressionRanges != null) {
return this.recommendationSuppressionRanges;
}

List<Range> recommendationSuppressionRanges = new ArrayList<>();
for (int i = 0; rawContent != null && i < rawContent.size(); i++) {
String lineStr = rawContent.get(i);
int startColumnIgnore = lineStr.indexOf(AnnotationType.IGNORE.value());
Expand All @@ -141,7 +149,7 @@ public List<Range> getRecommendationSuppressionRanges() {
if (endColumn == -1) {
// we found a sldsValidatorIgnore with no sldsValidatorAllow after it
// so we should exempt the rest of the lines.
lintingIgnoreRanges.add(
recommendationSuppressionRanges.add(
new Range(
new Location(i, startColumnIgnore),
new Location(Integer.MAX_VALUE, Integer.MAX_VALUE)
Expand All @@ -151,7 +159,7 @@ public List<Range> getRecommendationSuppressionRanges() {
} else {
// we found a sldsValidatorIgnore with sldsValidatorAllow after it
// so we should exempt the lines in between.
lintingIgnoreRanges.add(
recommendationSuppressionRanges.add(
new Range(
new Location(i, startColumnIgnore),
new Location(j, endColumn)
Expand All @@ -161,7 +169,7 @@ public List<Range> getRecommendationSuppressionRanges() {
}
} else if (startColumnIgnoreNextLine >= 0) {
// we found a sldsValidatorIgnoreNextLine so we should exempt the next line.
lintingIgnoreRanges.add(
recommendationSuppressionRanges.add(
new Range(
new Location(i + 1, 0),
new Location(i + 1, Integer.MAX_VALUE)
Expand All @@ -170,7 +178,24 @@ public List<Range> getRecommendationSuppressionRanges() {
i++; // skip the next line
}
}
return lintingIgnoreRanges;

/**
* Special Processing for CSS Annotation
*/
List<Annotation> annotations = getAnnotations();
if (annotations.size() > 0) {
List<Annotation> inlineAnnotations = annotations.stream().filter(annotation ->
annotation.getScope() == AnnotationScope.INLINE).collect(Collectors.toList());

this.recommendationSuppressionRanges = recommendationSuppressionRanges.stream().filter(suppressionRange ->
!inlineAnnotations.stream().anyMatch(inlineItem ->
inlineItem.getRange().getStart().equals(suppressionRange.getStart()))
).collect(Collectors.toList());
} else {
this.recommendationSuppressionRanges = recommendationSuppressionRanges;
}

return this.recommendationSuppressionRanges;
}

public List<String> getRawContent() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -187,9 +187,18 @@ private Annotation getAnnotation(Style style) {
AnnotationType annotationType = style.getAnnotationType();

if (annotationType != null) {

String lineToCheck = raw.get(style.getRange().getStart().getLine() + 1 - getRule().line());

Location endLocation = new Location(style.getRange().getStart().getLine(),
lineToCheck.lastIndexOf(annotationType.value()) + annotationType.value().length());
Location startLocation = new Location(endLocation.getLine(), endLocation.getColumn() -
annotationType.value().length());

return Annotation.builder()
.type(annotationType)
.style(style)
.range(new Range(startLocation, endLocation))
.scope(AnnotationScope.INLINE).build();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
package com.salesforce.slds.shared.models.core;

import com.salesforce.slds.shared.models.annotations.AnnotationType;
import com.salesforce.slds.shared.models.context.Context;
import com.salesforce.slds.shared.models.context.ContextKey;
import com.salesforce.slds.shared.models.locations.Range;
import com.salesforce.slds.shared.models.locations.RangeProvider;
import org.apache.commons.lang3.builder.EqualsBuilder;
Expand Down Expand Up @@ -52,10 +54,14 @@ public String getCondition() {

public AnnotationType getAnnotationType() {return annotationType;}

public Boolean validate() {
public Boolean validate(Context context) {

if (getAnnotationType() != null && getAnnotationType().validate() == false) {
return false;
if (getAnnotationType() != null) {
if (context.isEnabled(ContextKey.V2_ANNOTATION)) {
return getAnnotationType().validate();
} else {
return getAnnotationType() != AnnotationType.ALLOW;
}
}

return true;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,12 @@
package com.salesforce.slds.shared.parsers.css;

import com.salesforce.omakase.Omakase;
import com.salesforce.omakase.ast.CssAnnotation;
import com.salesforce.omakase.ast.Rule;
import com.salesforce.omakase.plugin.core.SyntaxTree;
import com.salesforce.slds.shared.models.annotations.AnnotationType;
import com.salesforce.slds.shared.models.context.Context;
import com.salesforce.slds.shared.models.context.ContextKey;
import com.salesforce.slds.shared.models.core.RuleSet;
import com.salesforce.slds.shared.models.locations.Location;
import com.salesforce.slds.shared.models.locations.Range;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,13 @@

package com.salesforce.slds.validation.processors;

import com.salesforce.slds.shared.models.context.Context;
import com.salesforce.slds.shared.models.core.Entry;
import com.salesforce.slds.shared.models.recommendation.Recommendation;

import java.util.List;

public interface Processor {

List<Recommendation> process(Entry entry, List<Recommendation> recommendations);
List<Recommendation> process(Context context, Entry entry, List<Recommendation> recommendations);
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,32 +7,36 @@

package com.salesforce.slds.validation.processors;

import com.salesforce.slds.shared.models.context.Context;
import com.salesforce.slds.shared.models.context.ContextKey;
import com.salesforce.slds.shared.models.core.Entry;
import com.salesforce.slds.shared.models.core.HTMLElement;
import com.salesforce.slds.shared.models.core.Input;
import com.salesforce.slds.shared.models.locations.Range;
import com.salesforce.slds.shared.models.recommendation.Action;
import com.salesforce.slds.shared.models.recommendation.ActionType;
import com.salesforce.slds.shared.models.recommendation.Item;
import com.salesforce.slds.shared.models.recommendation.Recommendation;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Component;

import java.util.*;
import java.util.Comparator;
import java.util.List;
import java.util.Set;
import java.util.TreeSet;
import java.util.stream.Collectors;
import java.util.stream.Stream;

@Component
@Lazy
public class SortAndFilterProcessor implements Processor {

@Override
public List<Recommendation> process(Entry entry, List<Recommendation> recommendations) {
public List<Recommendation> process(Context context, Entry entry, List<Recommendation> recommendations) {
List<Range> ranges = extractUtilitiesRange(recommendations);
List<Range> recommendationSuppressionRanges = entry.getRecommendationSuppressionRanges();

return recommendations.stream()
.filter(recommendation -> containItems(recommendation) && filter(recommendation, ranges))
.filter(recommendation -> !shouldSkipRecommendation(recommendationSuppressionRanges, recommendation))
.filter(recommendation -> !shouldSkipRecommendation(context,
recommendationSuppressionRanges, recommendation))
.map(this::sort)
.sorted(Recommendation::compareTo)
.collect(Collectors.toList());
Expand Down Expand Up @@ -67,28 +71,25 @@ Recommendation sort(Recommendation recommendation) {
return recommendation;
}

private boolean shouldSkipRecommendation(List<Range> recommendationSuppressionRanges, Recommendation recommendation) {
HTMLElement element = recommendation.getElement();

// For now we only apply the filtering to inputs of type Markup. This is because CSS
// files are filtered differently (using annotations) at the time when recommendations
// are being created, and that filtering logic is a bit different. So if we applied the
// filtering to CSS files here as well, then it would break backwards compatibility.
// Once we figure out a good way to address backwards compatibility, we should update
// this here to include all file types using the exact filtering logic used here
// in order to keep things consistent.
if (element == null) {
private boolean shouldSkipRecommendation(Context context,
List<Range> recommendationSuppressionRanges,
Recommendation recommendation) {
Set<Item> items = recommendation.getItems();
Input.Type inputType = recommendation.getInput().getType();

if (!context.isEnabled(ContextKey.V2_ANNOTATION) && inputType != Input.Type.MARKUP) {
return false;
}

Range elementRange = element.getRange();
return recommendationSuppressionRanges.stream().anyMatch(range ->
range.within(elementRange) || // completely contained withing the ignore range
items.stream().anyMatch( item -> item.getActions().stream().anyMatch( action ->

range.within(action.getRange()) || // completely contained withing the ignore range
(
// next line is meant to be ignored and the element indeed starts as the next line
range.getStart().getLine() == range.getEnd().getLine() &&
range.getStart().getLine() == elementRange.getStart().getLine()
)
range.getStart().getLine() == action.getRange().getStart().getLine()
)))
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ public void run() {
.flatMap(List::stream)
.collect(aggregator.toList());

entry.setRecommendation(processor.process(entry, recommendations));
entry.setRecommendation(processor.process(context, entry, recommendations));

List<ComponentOverride> overrides = validators.parallelStream()
.filter(validator -> validator instanceof OverrideValidator)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
package com.salesforce.slds.validation.utils;

import com.salesforce.slds.shared.converters.Converter;
import com.salesforce.slds.shared.models.context.Context;
import com.salesforce.slds.shared.models.core.Entry;
import com.salesforce.slds.shared.models.core.Style;
import com.salesforce.slds.shared.models.locations.Location;
Expand Down Expand Up @@ -37,8 +38,9 @@ public CSSValidationUtilities(ValueUtilities valueUtilities, ActionUtilities act
this.actionUtilities = actionUtilities;
}

public Recommendation match(Style style, List<DesignToken> tokens, Entry.EntityType entityType, List<String> rawContent) {
if (style.validate() == false) {
public Recommendation match(Context context, Style style, List<DesignToken> tokens,
Entry.EntityType entityType, List<String> rawContent) {
if (style.validate(context) == false) {
return null;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ public List<Recommendation> matches(Entry entry, Bundle bundle, Context context)
.map(RuleSet::getStylesWithAnnotationType)
.flatMap(List::stream)
.filter(style -> utilities.filter(style, getProperties()))
.map(style -> utilities.match(style, applicableTokens, entry.getEntityType(), entry.getRawContent()))
.map(style -> utilities.match(context, style, applicableTokens, entry.getEntityType(), entry.getRawContent()))
.filter(Objects::nonNull)
.collect(Collectors.toList());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ public List<Recommendation> matches(Entry entry, Bundle bundle, Context context
for (Input input : inputs) {
List<Style> styles = input.asRuleSet().getStylesWithAnnotationType();
recommendations.addAll(styles.stream()
.filter(Style::validate)
.filter(style -> style.validate(context))
.map(style -> process(style, context, entry.getRawContent()))
.filter(Objects::nonNull)
.collect(Collectors.toList()));
Expand Down
Loading