/** * @param Context $context * * @return Node|RulesetNode */ public function callCompile(Context $context) { if ($this->frames) { return $this->ruleset->compile(Context::createCopyForCompilation($context, array_merge($this->frames, $context->frames))); } return $this->ruleset->compile($context); }
/** * Does the import * * @param ImportedFile $file The imported file * @param string $path The original path * @param FileInfo $currentFileInfo Current file info * @param array $importOptions Import options * @param boolean $fromCache Is the imported file coming from cache? * @throws ParserException * @throws Exception * @return array */ protected function doImport(ImportedFile $file, $path, FileInfo $currentFileInfo, array $importOptions = [], $fromCache = false) { $newEnv = Context::createCopyForCompilation($this->context, $this->context->frames); $newFileInfo = clone $currentFileInfo; if ($this->context->relativeUrls) { // Pass on an updated rootPath if path of imported file is relative and file // is in a (sub|sup) directory // // Examples: // - If path of imported file is 'module/nav/nav.less' and rootPath is 'less/', // then rootPath should become 'less/module/nav/' // - If path of imported file is '../mixins.less' and rootPath is 'less/', // then rootPath should become 'less/../' if (!Util::isPathAbsolute($path) && ($lastSlash = strrpos($path, '/')) !== false) { $relativeSubDirectory = substr($path, 0, $lastSlash + 1); $newFileInfo->rootPath = $newFileInfo->rootPath . $relativeSubDirectory; } } // we need to clone here, to prevent modification of node current info object $newEnv->currentFileInfo = $newFileInfo; $newEnv->processImports = false; if ($currentFileInfo->reference || isset($importOptions['reference']) && $importOptions['reference']) { $newEnv->currentFileInfo->reference = true; } $key = $file->getPath(); $root = null; $alreadyImported = false; // check for already imported file if (isset($this->importedFiles[$key])) { $alreadyImported = true; } elseif (!$file->getRuleset()) { try { // we do not parse the root but load the file as is if (isset($importOptions['inline']) && $importOptions['inline']) { $root = $file->getContent(); } else { $parser = new Core($newEnv, $this, $this->pluginManager); $root = $parser->parseFile($file, true); $root->root = false; $root->firstRoot = false; } $file->setRuleset($root); // we need to catch parse exceptions } catch (Exception $e) { // rethrow throw $e; } catch (\Exception $error) { $file->setError($error); } $this->setImportedFile($key, $file, $path, $currentFileInfo); } else { $this->setImportedFile($key, $file, $path, $currentFileInfo); } if ($fromCache) { $ruleset = $this->importedFiles[$key][0]->getRuleset(); if ($ruleset instanceof Node) { // this is a workaround for reference and import one issues when taken cache $this->updateReferenceInCurrentFileInfo($ruleset, $newEnv->currentFileInfo); } } return [$alreadyImported, $this->importedFiles[$key][0]]; }
/** * Match condition. * * @param array $arguments * @param Context $context * * @return bool */ public function matchCondition(array $arguments, Context $context) { $lastSelector = $this->selectors[count($this->selectors) - 1]; if (!$lastSelector->compiledCondition) { return false; } if ($lastSelector->condition && !$lastSelector->condition->compile(Context::createCopyForCompilation($context, $context->frames))) { return false; } return true; }
/** * Match a condition. * * @param array $arguments * @param Context $context * * @return bool */ public function matchCondition(array $arguments, Context $context) { if (!$this->condition) { return true; } $frame = $this->compileParams($context, Context::createCopyForCompilation($context, array_merge($this->frames, $context->frames)), $arguments); $compileEnv = Context::createCopyForCompilation($context, array_merge([$frame], $this->frames, $context->frames)); if (!$this->condition->compile($compileEnv)) { return false; } return true; }
/** * Visits a import node. * * @param ImportNode $node The node * @param VisitorArguments $arguments The arguments * * @return ImportNode */ public function visitImport(ImportNode $node, VisitorArguments $arguments) { if (!$node->css || $node->getOption('inline')) { $context = Context::createCopyForCompilation($this->context, $this->context->frames); $importParent = $context->frames[0]; ++$this->importCount; if ($node->isVariableImport()) { $this->sequencer->addVariableImport(function () use($node, $context, $importParent) { $this->processImportNode($node, $context, $importParent); }); } else { $this->sequencer->addImport(function () use($node, $context, $importParent) { $this->processImportNode($node, $context, $importParent); }); } } $arguments->visitDeeper = false; return $node; }