Skip to content

Commit

Permalink
Added import option inline #126
Browse files Browse the repository at this point in the history
  • Loading branch information
meri committed Feb 15, 2014
1 parent 803941f commit ac446a4
Show file tree
Hide file tree
Showing 11 changed files with 158 additions and 16 deletions.
7 changes: 6 additions & 1 deletion src/main/antlr3/com/github/sommeri/less4j/core/parser/Less.g
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ tokens {
MEDIUM_DECLARATION;
MEDIA_EXPRESSION;
INTERPOLATED_MEDIA_EXPRESSION;
IMPORT_OPTIONS;
MEDIA_QUERY;
MEDIUM_TYPE;
BODY;
Expand Down Expand Up @@ -204,10 +205,14 @@ finally { leaveRule(); }
//
imports
@init {enterRule(retval, RULE_IMPORTS);}
: (IMPORT_SYM | IMPORT_ONCE_SYM | IMPORT_MULTIPLE_SYM)^ (term) (mediaQuery (COMMA mediaQuery)*)? SEMI!
: (IMPORT_SYM | IMPORT_ONCE_SYM | IMPORT_MULTIPLE_SYM)^ (importoptions)? term (mediaQuery (COMMA mediaQuery)*)? SEMI!
;
finally { leaveRule(); }

importoptions:
LPAREN a+=IDENT+ RPAREN
-> ^(IMPORT_OPTIONS $a*)
;
// ---------
// Media. Introduce a set of rules that are to be used if the consumer indicates
// it belongs to the signified medium.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
package com.github.sommeri.less4j.core.ast;

public enum ASTCssNodeType {
UNKNOWN, CSS_CLASS, DECLARATION, STYLE_SHEET, RULE_SET, SELECTOR, SIMPLE_SELECTOR, PSEUDO_CLASS, PSEUDO_ELEMENT, SELECTOR_ATTRIBUTE, ID_SELECTOR, CHARSET_DECLARATION, FONT_FACE, IDENTIFIER_EXPRESSION, COMPOSED_EXPRESSION, STRING_EXPRESSION, NUMBER, COLOR_EXPRESSION, FUNCTION, MEDIA, COMMENT, SELECTOR_OPERATOR, SELECTOR_COMBINATOR, EXPRESSION_OPERATOR, NTH, NAMED_EXPRESSION, MEDIA_QUERY, FIXED_MEDIA_EXPRESSION, MEDIUM, MEDIUM_MODIFIER, MEDIUM_TYPE, MEDIUM_EX_FEATURE, VARIABLE_DECLARATION, VARIABLE, INDIRECT_VARIABLE, PARENTHESES_EXPRESSION, SIGNED_EXPRESSION, ARGUMENT_DECLARATION, MIXIN_REFERENCE, GUARD_CONDITION, COMPARISON_EXPRESSION, GUARD, NESTED_SELECTOR_APPENDER, REUSABLE_STRUCTURE, FAULTY_EXPRESSION, ESCAPED_SELECTOR, ESCAPED_VALUE, INTERPOLABLE_NAME, FIXED_NAME_PART, VARIABLE_NAME_PART, KEYFRAMES, KEYFRAMES_NAME, REUSABLE_STRUCTURE_NAME, VIEWPORT, GENERAL_BODY, PAGE, NAME, PAGE_MARGIN_BOX, IMPORT, FAULTY_NODE, ANONYMOUS, EMPTY_EXPRESSION, SYNTAX_ONLY_ELEMENT, UNICODE_RANGE_EXPRESSION, INTERPOLATED_MEDIA_EXPRESSION, DOCUMENT, SUPPORTS, SUPPORTS_QUERY, SUPPORTS_CONDITION_NEGATION, SUPPORTS_CONDITION_PARENTHESES, SUPPORTS_CONDITION_LOGICAL, SUPPORTS_LOGICAL_OPERATOR, EXTEND
UNKNOWN, CSS_CLASS, DECLARATION, STYLE_SHEET, RULE_SET, SELECTOR, SIMPLE_SELECTOR, PSEUDO_CLASS, PSEUDO_ELEMENT, SELECTOR_ATTRIBUTE, ID_SELECTOR, CHARSET_DECLARATION, FONT_FACE, IDENTIFIER_EXPRESSION, COMPOSED_EXPRESSION, STRING_EXPRESSION, NUMBER, COLOR_EXPRESSION, FUNCTION, MEDIA, COMMENT, SELECTOR_OPERATOR, SELECTOR_COMBINATOR, EXPRESSION_OPERATOR, NTH, NAMED_EXPRESSION, MEDIA_QUERY, FIXED_MEDIA_EXPRESSION, MEDIUM, MEDIUM_MODIFIER, MEDIUM_TYPE, MEDIUM_EX_FEATURE, VARIABLE_DECLARATION, VARIABLE, INDIRECT_VARIABLE, PARENTHESES_EXPRESSION, SIGNED_EXPRESSION, ARGUMENT_DECLARATION, MIXIN_REFERENCE, GUARD_CONDITION, COMPARISON_EXPRESSION, GUARD, NESTED_SELECTOR_APPENDER, REUSABLE_STRUCTURE, FAULTY_EXPRESSION, ESCAPED_SELECTOR, ESCAPED_VALUE, INTERPOLABLE_NAME, FIXED_NAME_PART, VARIABLE_NAME_PART, KEYFRAMES, KEYFRAMES_NAME, REUSABLE_STRUCTURE_NAME, VIEWPORT, GENERAL_BODY, PAGE, NAME, PAGE_MARGIN_BOX, IMPORT, FAULTY_NODE, ANONYMOUS, EMPTY_EXPRESSION, SYNTAX_ONLY_ELEMENT, UNICODE_RANGE_EXPRESSION, INTERPOLATED_MEDIA_EXPRESSION, DOCUMENT, SUPPORTS, SUPPORTS_QUERY, SUPPORTS_CONDITION_NEGATION, SUPPORTS_CONDITION_PARENTHESES, SUPPORTS_CONDITION_LOGICAL, SUPPORTS_LOGICAL_OPERATOR, EXTEND, INLINE_CONTENT
}
21 changes: 15 additions & 6 deletions src/main/java/com/github/sommeri/less4j/core/ast/Import.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,20 +9,29 @@

public class Import extends ASTCssNode {

private ImportKind kind = ImportKind.IMPORT;
private ImportMultiplicity multiplicity = ImportMultiplicity.IMPORT;
private boolean isInline = false;
private Expression urlExpression;
private List<MediaQuery> mediums = new ArrayList<MediaQuery>();

public Import(HiddenTokenAwareTree underlyingStructure) {
super(underlyingStructure);
}

public ImportKind getKind() {
return kind;
public boolean isInline() {
return isInline;
}

public void setKind(ImportKind kind) {
this.kind = kind;
public void setInline(boolean isInline) {
this.isInline = isInline;
}

public ImportMultiplicity getMultiplicity() {
return multiplicity;
}

public void setMultiplicity(ImportMultiplicity multiplicity) {
this.multiplicity = multiplicity;
}

public Expression getUrlExpression() {
Expand Down Expand Up @@ -71,7 +80,7 @@ public ASTCssNodeType getType() {
return ASTCssNodeType.IMPORT;
}

public enum ImportKind {
public enum ImportMultiplicity {
IMPORT, IMPORT_ONCE, IMPORT_MULTIPLE
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package com.github.sommeri.less4j.core.ast;

import java.util.Collections;
import java.util.List;

import com.github.sommeri.less4j.core.ast.annotations.NotAstProperty;
import com.github.sommeri.less4j.core.parser.HiddenTokenAwareTree;

public class InlineContent extends ASTCssNode {

private String value;

public InlineContent(HiddenTokenAwareTree token, String value) {
super(token);
this.value = value;
}

public String getValue() {
return value;
}

public void setValue(String value) {
this.value = value;
}

@Override
public ASTCssNodeType getType() {
return ASTCssNodeType.INLINE_CONTENT;
}

@Override
@NotAstProperty
public List<? extends ASTCssNode> getChilds() {
return Collections.emptyList();
}

@Override
public String toString() {
return "" + value;
}

@Override
public InlineContent clone() {
return (InlineContent) super.clone();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@
import com.github.sommeri.less4j.core.ast.FaultyNode;
import com.github.sommeri.less4j.core.ast.GeneralBody;
import com.github.sommeri.less4j.core.ast.Import;
import com.github.sommeri.less4j.core.ast.Import.ImportKind;
import com.github.sommeri.less4j.core.ast.InlineContent;
import com.github.sommeri.less4j.core.ast.Import.ImportMultiplicity;
import com.github.sommeri.less4j.core.ast.Media;
import com.github.sommeri.less4j.core.ast.StyleSheet;
import com.github.sommeri.less4j.core.compiler.expressions.TypesConversionUtils;
Expand Down Expand Up @@ -101,6 +102,17 @@ public ASTCssNode importEncountered(Import node, LessSource source) {
return null;
}

if (node.isInline()) {
HiddenTokenAwareTree underlyingStructure = node.getUnderlyingStructure();
StyleSheet result = new StyleSheet(underlyingStructure);
InlineContent content = new InlineContent(underlyingStructure, importedContent);
result.addMember(content);
result.configureParentToAllChilds();

astManipulator.replaceInBody(node, content);
return result;
}

// parse imported file
StyleSheet importedAst = parseContent(node, importedContent, importedSource);

Expand All @@ -127,7 +139,7 @@ public ASTCssNode importEncountered(Import node, LessSource source) {
}

private boolean isImportOnce(Import node) {
return node.getKind() == ImportKind.IMPORT_ONCE;
return node.getMultiplicity() == ImportMultiplicity.IMPORT_ONCE;
}

private boolean alreadyVisited(LessSource importedSource) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,13 @@ class ASTBuilderSwitch extends TokenTypeSwitch<ASTCssNode> {
}

private final static String EXTEND_ALL_KEYWORD = "all";

private final static String IMPORT_OPTION_REFERENCE = "reference";
private final static String IMPORT_OPTION_INLINE = "inline";
private final static String IMPORT_OPTION_LESS = "less";
private final static String IMPORT_OPTION_CSS = "css";
private final static String IMPORT_OPTION_ONCE = "once";
private final static String IMPORT_OPTION_MULTIPLE = "multiple";

public ASTBuilderSwitch(ProblemsHandler problemsHandler) {
super();
Expand Down Expand Up @@ -1060,20 +1067,25 @@ public Import handleImport(HiddenTokenAwareTree token) {
Import result = new Import(token);
switch (token.getType()) {
case LessLexer.IMPORT_SYM:
result.setKind(Import.ImportKind.IMPORT);
result.setMultiplicity(Import.ImportMultiplicity.IMPORT);
break;
case LessLexer.IMPORT_ONCE_SYM:
result.setKind(Import.ImportKind.IMPORT_ONCE);
result.setMultiplicity(Import.ImportMultiplicity.IMPORT_ONCE);
break;
case LessLexer.IMPORT_MULTIPLE_SYM:
result.setKind(Import.ImportKind.IMPORT_MULTIPLE);
result.setMultiplicity(Import.ImportMultiplicity.IMPORT_MULTIPLE);
break;
default:
throw new BugHappened(GRAMMAR_MISMATCH, token);
}

Iterator<HiddenTokenAwareTree> children = token.getChildren().iterator();
result.setUrlExpression(handleTerm(children.next()));
HiddenTokenAwareTree nextChild = children.next();
if (nextChild.getType() == LessLexer.IMPORT_OPTIONS) {
configureImportOptions(result, nextChild.getChildren());
nextChild = children.next();
}

result.setUrlExpression(handleTerm(nextChild));
while (children.hasNext()) {
HiddenTokenAwareTree kid = children.next();
if (kid.getType() == LessLexer.COMMA) {
Expand All @@ -1088,6 +1100,17 @@ public Import handleImport(HiddenTokenAwareTree token) {
return result;
}

private void configureImportOptions(Import node, List<HiddenTokenAwareTree> options) {
for (HiddenTokenAwareTree token : options) {
String text = token.getText();
if (IMPORT_OPTION_INLINE.equals(text)) {
node.setInline(true);
} else {
problemsHandler.unknownImportOption(node, text);
}
}
}

public NamedExpression handleNamedExpression(HiddenTokenAwareTree token) {
HiddenTokenAwareTree nameToken = token.getChild(0);
HiddenTokenAwareTree valueToken = token.getChild(1);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import com.github.sommeri.less4j.core.ast.EscapedSelector;
import com.github.sommeri.less4j.core.ast.Expression;
import com.github.sommeri.less4j.core.ast.FunctionExpression;
import com.github.sommeri.less4j.core.ast.Import;
import com.github.sommeri.less4j.core.ast.MediaQuery;
import com.github.sommeri.less4j.core.ast.MixinReference;
import com.github.sommeri.less4j.core.ast.NestedSelectorAppender;
Expand Down Expand Up @@ -59,6 +60,10 @@ public void warnMerginMediaQueryWithMedium(MediaQuery mediaQuery) {
collector.addWarning(new CompilationWarning(mediaQuery, "Attempt to merge media query with a medium. Merge removed medium from inner media query, because the result CSS would be invalid otherwise."));
}

public void unknownImportOption(Import node, String text) {
collector.addError(new CompilationError(node, "Unknown import option \"" + text));
}

public void warnInconsistentSupportsLogicalConditionOperators(SupportsLogicalOperator faulty, SupportsLogicalOperator masterOperator) {
String faultySymbol = faulty.getOperator().getSymbol();
String masterSymbol = masterOperator.getOperator().getSymbol();
Expand Down
10 changes: 10 additions & 0 deletions src/main/java/com/github/sommeri/less4j/utils/CssPrinter.java
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
import com.github.sommeri.less4j.core.ast.IdSelector;
import com.github.sommeri.less4j.core.ast.IdentifierExpression;
import com.github.sommeri.less4j.core.ast.Import;
import com.github.sommeri.less4j.core.ast.InlineContent;
import com.github.sommeri.less4j.core.ast.InterpolableName;
import com.github.sommeri.less4j.core.ast.InterpolatedMediaExpression;
import com.github.sommeri.less4j.core.ast.Keyframes;
Expand Down Expand Up @@ -278,6 +279,9 @@ public boolean switchOnType(ASTCssNode node) {
case SUPPORTS_LOGICAL_OPERATOR:
return appendSupportsLogicalOperator((SupportsLogicalOperator) node); // TODOsm: source map

case INLINE_CONTENT:
return appendInlineContent((InlineContent) node); // TODOsm: source map

case ESCAPED_SELECTOR:
case PARENTHESES_EXPRESSION:
case SIGNED_EXPRESSION:
Expand All @@ -291,6 +295,12 @@ public boolean switchOnType(ASTCssNode node) {
}
}

//TODO: what about source maps?
private boolean appendInlineContent(InlineContent node) {
cssOnly.appendAsIs(node.getValue());
return false;
}

private boolean appendSyntaxOnlyElement(SyntaxOnlyElement node) {
cssOnly.append(node.getSymbol());
return true;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
public class TokenNamesForErrorReportingTest {

private static final List<String> TECHNICAL_ANTLR = Arrays.asList("<invalid>", "<EOR>", "<DOWN>", "<UP>");
private static final List<String> FICTIONAL = Arrays.asList("ARGUMENT_DECLARATION", "VARIABLE_DECLARATION", "ARGUMENT_COLLECTOR", "EXPRESSION", "DECLARATION", "VARIABLE_REFERENCE", "RULESET", "NESTED_APPENDER", "EXTENDED_SELECTOR", "SELECTOR", "SIMPLE_SELECTOR", "ESCAPED_SELECTOR", "EXPRESSION_PARENTHESES", "ESCAPED_VALUE", "STYLE_SHEET", "EMPTY_SEPARATOR", "ELEMENT_NAME", "CSS_CLASS", "NTH", "PSEUDO", "ATTRIBUTE", "ID_SELECTOR", "ELEMENT_SUBSEQUENT", "CHARSET_DECLARATION", "TERM_FUNCTION", "TERM", "MEDIUM_DECLARATION", "FIXED_MEDIA_EXPRESSION", "MEDIA_QUERY", "MEDIUM_TYPE", "BODY", "MIXIN_REFERENCE", "NAMESPACE_REFERENCE", "REUSABLE_STRUCTURE", "MIXIN_PATTERN", "GUARD_CONDITION", "GUARD", "DUMMY_MEANINGFULL_WHITESPACE", "KEYFRAMES", "DOCUMENT_DECLARATION", "REUSABLE_STRUCTURE_NAME", "VIEWPORT");
private static final List<String> FICTIONAL = Arrays.asList("IMPORT_OPTIONS", "ARGUMENT_DECLARATION", "VARIABLE_DECLARATION", "ARGUMENT_COLLECTOR", "EXPRESSION", "DECLARATION", "VARIABLE_REFERENCE", "RULESET", "NESTED_APPENDER", "EXTENDED_SELECTOR", "SELECTOR", "SIMPLE_SELECTOR", "ESCAPED_SELECTOR", "EXPRESSION_PARENTHESES", "ESCAPED_VALUE", "STYLE_SHEET", "EMPTY_SEPARATOR", "ELEMENT_NAME", "CSS_CLASS", "NTH", "PSEUDO", "ATTRIBUTE", "ID_SELECTOR", "ELEMENT_SUBSEQUENT", "CHARSET_DECLARATION", "TERM_FUNCTION", "TERM", "MEDIUM_DECLARATION", "FIXED_MEDIA_EXPRESSION", "MEDIA_QUERY", "MEDIUM_TYPE", "BODY", "MIXIN_REFERENCE", "NAMESPACE_REFERENCE", "REUSABLE_STRUCTURE", "MIXIN_PATTERN", "GUARD_CONDITION", "GUARD", "DUMMY_MEANINGFULL_WHITESPACE", "KEYFRAMES", "DOCUMENT_DECLARATION", "REUSABLE_STRUCTURE_NAME", "VIEWPORT");
private static final List<String> TECHNICAL_LESS4J = Arrays.asList("SEMI_SPLIT_MIXIN_DECLARATION_ARGUMENTS", "SEMI_SPLIT_MIXIN_REFERENCE_ARGUMENTS", "UNICODE_RANGE_HEX","TERM_FUNCTION_NAME", "NMSTART", "NMCHAR", "NAME", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z");

@Test
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
first {
first: first;
}
@variable: @fromImporter;

.mixin() {
content: ~"@variable value is" @variable;
}

#space {
.mixin() {
content: ~"mixin in space";
}
}
div {
location: main;
variable: main;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
first {
first: first;
}
@variable: main;
@import (inline) "import/namespaces-and-mixins.less";

.mixin() {
location: main;
}
@fromImporter: value;
div {
.mixin();
variable: @variable;
}

0 comments on commit ac446a4

Please sign in to comment.