Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(760)

Unified Diff: pkg/csslib/lib/src/polyfill.dart

Issue 23819036: Support for @mixin, @include and @extend (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: All changes ready to commit Created 7 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « pkg/csslib/lib/src/options.dart ('k') | pkg/csslib/lib/src/tokenkind.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: pkg/csslib/lib/src/polyfill.dart
diff --git a/pkg/csslib/lib/src/polyfill.dart b/pkg/csslib/lib/src/polyfill.dart
index ab56771e6861535fd9c176c9f600835063ea76ca..ef3c7b97d455457048a8b974a9a421a8c07d4dd7 100644
--- a/pkg/csslib/lib/src/polyfill.dart
+++ b/pkg/csslib/lib/src/polyfill.dart
@@ -1,4 +1,4 @@
-// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
+// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
@@ -11,6 +11,8 @@ part of csslib.parser;
class PolyFill {
final Messages _messages;
final bool _warningsAsErrors;
+ Map<String, VarDefinition> _allVarDefinitions =
+ new Map<String, VarDefinition>();
Set<StyleSheet> allStyleSheets = new Set<StyleSheet>();
@@ -25,55 +27,45 @@ class PolyFill {
* Run the analyzer on every file that is a style sheet or any component that
* has a style tag.
*/
- void process(StyleSheet stylesheet) {
- // TODO(terry): Process all imported stylesheets.
-
- var styleSheets = processVars([stylesheet]);
- allStyleSheets.addAll(styleSheets);
+ void process(StyleSheet styleSheet, {List<StyleSheet> includes: null}) {
+ if (includes != null) {
+ processVarDefinitions(includes);
+ }
+ processVars(styleSheet);
- normalize();
+ // Remove all var definitions for this style sheet.
+ new _RemoveVarDefinitions().visitTree(styleSheet);
}
- void normalize() {
- // Remove all var definitions for all style sheets analyzed.
- for (var tree in allStyleSheets)
- new _RemoveVarDefinitions().visitTree(tree);
+ /** Process all includes looking for var definitions. */
+ void processVarDefinitions(List<StyleSheet> includes) {
+ for (var include in includes) {
+ _allVarDefinitions = (new _VarDefinitionsIncludes(_allVarDefinitions)
+ ..visitTree(include)).varDefs;
+ }
}
- List<StyleSheet> processVars(List<StyleSheet> styleSheets) {
- // TODO(terry): Process all dependencies.
+ void processVars(StyleSheet styleSheet) {
// Build list of all var definitions.
- Map varDefs = new Map();
- for (var tree in styleSheets) {
- var allDefs = (new _VarDefinitions()..visitTree(tree)).found;
- allDefs.forEach((key, value) {
- varDefs[key] = value;
- });
- }
+ var mainStyleSheetVarDefs =
+ (new _VarDefAndUsage(this._messages, _allVarDefinitions)
+ ..visitTree(styleSheet)).varDefs;
// Resolve all definitions to a non-VarUsage (terminal expression).
- varDefs.forEach((key, value) {
- for (var expr in (value.expression as Expressions).expressions) {
- var def = _findTerminalVarDefinition(varDefs, value);
- varDefs[key] = def;
+ mainStyleSheetVarDefs.forEach((key, value) {
+ for (Expression expr in (value.expression as Expressions).expressions) {
+ mainStyleSheetVarDefs[key] =
+ _findTerminalVarDefinition(_allVarDefinitions, value);
}
});
-
- // Resolve all var usages.
- for (var tree in styleSheets) {
- new _ResolveVarUsages(varDefs).visitTree(tree);
- }
-
- return styleSheets;
}
}
-/**
- * Find var- definitions in a style sheet.
- * [found] list of known definitions.
- */
-class _VarDefinitions extends Visitor {
- final Map<String, VarDefinition> found = new Map();
+/** Build list of all var definitions in all includes. */
+class _VarDefinitionsIncludes extends Visitor {
+ final Map<String, VarDefinition> varDefs;
+
+ _VarDefinitionsIncludes(this.varDefs);
void visitTree(StyleSheet tree) {
visitStyleSheet(tree);
@@ -81,9 +73,9 @@ class _VarDefinitions extends Visitor {
visitVarDefinition(VarDefinition node) {
// Replace with latest variable definition.
- found[node.definedName] = node;
+ varDefs[node.definedName] = node;
super.visitVarDefinition(node);
- }
+ }
void visitVarDefinitionDirective(VarDefinitionDirective node) {
visitVarDefinition(node.def);
@@ -91,78 +83,98 @@ class _VarDefinitions extends Visitor {
}
/**
- * Resolve any CSS expression which contains a var() usage to the ultimate real
- * CSS expression value e.g.,
- *
- * var-one: var(two);
- * var-two: #ff00ff;
- *
- * .test {
- * color: var(one);
- * }
- *
- * then .test's color would be #ff00ff
+ * Find var- definitions in a style sheet.
+ * [found] list of known definitions.
*/
-class _ResolveVarUsages extends Visitor {
- final Map<String, VarDefinition> varDefs;
- bool inVarDefinition = false;
- bool inUsage = false;
- Expressions currentExpressions;
+class _VarDefAndUsage extends Visitor {
+ final Messages _messages;
+ final Map<String, VarDefinition> _knownVarDefs;
+ final Map<String, VarDefinition> varDefs = new Map<String, VarDefinition>();
- _ResolveVarUsages(this.varDefs);
+ VarDefinition currVarDefinition;
+ List<Expression> currentExpressions;
+
+ _VarDefAndUsage(this._messages, this._knownVarDefs);
void visitTree(StyleSheet tree) {
visitStyleSheet(tree);
}
- void visitVarDefinition(VarDefinition varDef) {
- inVarDefinition = true;
- super.visitVarDefinition(varDef);
- inVarDefinition = false;
+ visitVarDefinition(VarDefinition node) {
+ // Replace with latest variable definition.
+ currVarDefinition = node;
+
+ _knownVarDefs[node.definedName] = node;
+ varDefs[node.definedName] = node;
+
+ super.visitVarDefinition(node);
+
+ currVarDefinition = null;
+ }
+
+ void visitVarDefinitionDirective(VarDefinitionDirective node) {
+ visitVarDefinition(node.def);
}
void visitExpressions(Expressions node) {
- currentExpressions = node;
+ currentExpressions = node.expressions;
super.visitExpressions(node);
currentExpressions = null;
}
void visitVarUsage(VarUsage node) {
+ if (currVarDefinition != null && currVarDefinition.badUsage) return;
+
// Don't process other var() inside of a varUsage. That implies that the
// default is a var() too. Also, don't process any var() inside of a
// varDefinition (they're just place holders until we've resolved all real
// usages.
- if (!inUsage && !inVarDefinition && currentExpressions != null) {
- var expressions = currentExpressions.expressions;
- var index = expressions.indexOf(node);
- assert(index >= 0);
- var def = varDefs[node.name];
- if (def != null) {
- // Found a VarDefinition use it.
- _resolveVarUsage(currentExpressions.expressions, index, def);
- } else if (node.defaultValues.any((e) => e is VarUsage)) {
- // Don't have a VarDefinition need to use default values resolve all
- // default values.
- var terminalDefaults = [];
- for (var defaultValue in node.defaultValues) {
- terminalDefaults.addAll(resolveUsageTerminal(defaultValue));
+ var expressions = currentExpressions;
+ var index = expressions.indexOf(node);
+ assert(index >= 0);
+ var def = _knownVarDefs[node.name];
+ if (def != null) {
+ if (def.badUsage) {
+ // Remove any expressions pointing to a bad var definition.
+ expressions.removeAt(index);
+ return;
+ }
+ _resolveVarUsage(currentExpressions, index,
+ _findTerminalVarDefinition(_knownVarDefs, def));
+ } else if (node.defaultValues.any((e) => e is VarUsage)) {
+ // Don't have a VarDefinition need to use default values resolve all
+ // default values.
+ var terminalDefaults = [];
+ for (var defaultValue in node.defaultValues) {
+ terminalDefaults.addAll(resolveUsageTerminal(defaultValue));
+ }
+ expressions.replaceRange(index, index + 1, terminalDefaults);
+ } else if (node.defaultValues.isNotEmpty){
+ // No VarDefinition but default value is a terminal expression; use it.
+ expressions.replaceRange(index, index + 1, node.defaultValues);
+ } else {
+ if (currVarDefinition != null) {
+ currVarDefinition.badUsage = true;
+ var mainStyleSheetDef = varDefs[node.name];
+ if (mainStyleSheetDef != null) {
+ varDefs.remove(currVarDefinition.property);
}
- expressions.replaceRange(index, index + 1, terminalDefaults);
- } else {
- // No VarDefinition but default value is a terminal expression; use it.
- expressions.replaceRange(index, index + 1, node.defaultValues);
}
+ // Remove var usage that points at an undefined definition.
+ expressions.removeAt(index);
+ _messages.warning("Variable is not defined.", node.span);
}
- inUsage = true;
+ var oldExpressions = currentExpressions;
+ currentExpressions = node.defaultValues;
super.visitVarUsage(node);
- inUsage = false;
+ currentExpressions = oldExpressions;
}
List<Expression> resolveUsageTerminal(VarUsage usage) {
var result = [];
- var varDef = varDefs[usage.name];
+ var varDef = _knownVarDefs[usage.name];
var expressions;
if (varDef == null) {
// VarDefinition not found try the defaultValues.
« no previous file with comments | « pkg/csslib/lib/src/options.dart ('k') | pkg/csslib/lib/src/tokenkind.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698