Index: runtime/vm/parser.cc |
diff --git a/runtime/vm/parser.cc b/runtime/vm/parser.cc |
index 15393a0d0b41b74017becaeb4d9af45f9354077c..54ebf29d9be6abdeae7c0e9ced51beb1fc105d60 100644 |
--- a/runtime/vm/parser.cc |
+++ b/runtime/vm/parser.cc |
@@ -49,6 +49,8 @@ DEFINE_FLAG(bool, trace_parser, false, "Trace parser operations."); |
DEFINE_FLAG(bool, warn_mixin_typedef, true, "Warning on legacy mixin typedef."); |
DEFINE_FLAG(bool, link_natives_lazily, false, "Link native calls lazily"); |
DEFINE_FLAG(bool, move_super, false, "Move super initializer to end of list"); |
+DEFINE_FLAG(bool, conditional_directives, false, |
+ "Enable conditional directives"); |
DECLARE_FLAG(bool, lazy_dispatchers); |
DECLARE_FLAG(bool, load_deferred_eagerly); |
@@ -5941,6 +5943,53 @@ void Parser::ParseLibraryImportExport(const Object& tl_owner, |
ConsumeToken(); |
CheckToken(Token::kSTRING, "library url expected"); |
AstNode* url_literal = ParseStringLiteral(false); |
+ if (FLAG_conditional_directives) { |
+ bool condition_triggered = false; |
+ while (CurrentToken() == Token::kIF) { |
+ // Conditional import: if (env == val) uri. |
+ ConsumeToken(); |
+ ExpectToken(Token::kLPAREN); |
+ // Parse dotted name. |
+ GrowableHandlePtrArray<const String> pieces(Z, 3); |
+ pieces.Add(*ExpectIdentifier("identifier expected")); |
+ while (CurrentToken() == Token::kPERIOD) { |
+ pieces.Add(Symbols::Dot()); |
+ ConsumeToken(); |
+ pieces.Add(*ExpectIdentifier("identifier expected")); |
+ } |
+ AstNode* valueNode = NULL; |
+ if (CurrentToken() == Token::kEQ) { |
+ ConsumeToken(); |
+ CheckToken(Token::kSTRING, "string literal expected"); |
+ valueNode = ParseStringLiteral(false); |
+ ASSERT(valueNode->IsLiteralNode()); |
+ ASSERT(valueNode->AsLiteralNode()->literal().IsString()); |
+ } |
+ ExpectToken(Token::kRPAREN); |
+ CheckToken(Token::kSTRING, "library url expected"); |
+ AstNode* conditional_url_literal = ParseStringLiteral(false); |
+ |
+ // If there was already a condition that triggered, don't try to match |
+ // again. |
+ if (condition_triggered) { |
+ continue; |
+ } |
+ // Check if this conditional line overrides the default import. |
+ // TODO(srdjan): Use Strings::FromConcatAll in old space, once |
+ // implemented. |
+ const String& key = String::Handle(Symbols::FromConcatAll(pieces)); |
Ivan Posva
2015/12/18 05:59:03
You should not be allocating a symbol here. A simp
floitsch
2015/12/18 13:40:57
Done.
|
+ const String& value = (valueNode == NULL) |
+ ? Symbols::True() |
+ : String::Cast(valueNode->AsLiteralNode()->literal()); |
+ // Call the embedder to supply us with the environment. |
+ const String& env_value = |
+ String::Handle(Api::CallEnvironmentCallback(thread(), key)); |
+ if (!env_value.IsNull() && env_value.Equals(value)) { |
+ condition_triggered = true; |
+ url_literal = conditional_url_literal; |
+ } |
+ } |
+ } |
ASSERT(url_literal->IsLiteralNode()); |
ASSERT(url_literal->AsLiteralNode()->literal().IsString()); |
const String& url = String::Cast(url_literal->AsLiteralNode()->literal()); |