| OLD | NEW |
| (Empty) |
| 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #include "tools/gn/import_manager.h" | |
| 6 | |
| 7 #include "base/memory/scoped_ptr.h" | |
| 8 #include "base/stl_util.h" | |
| 9 #include "tools/gn/parse_tree.h" | |
| 10 #include "tools/gn/scheduler.h" | |
| 11 | |
| 12 namespace { | |
| 13 | |
| 14 // Returns a newly-allocated scope on success, null on failure. | |
| 15 Scope* UncachedImport(const Settings* settings, | |
| 16 const SourceFile& file, | |
| 17 const ParseNode* node_for_err, | |
| 18 Err* err) { | |
| 19 const ParseNode* node = g_scheduler->input_file_manager()->SyncLoadFile( | |
| 20 node_for_err->GetRange(), settings->build_settings(), file, err); | |
| 21 if (!node) | |
| 22 return NULL; | |
| 23 const BlockNode* block = node->AsBlock(); | |
| 24 CHECK(block); | |
| 25 | |
| 26 scoped_ptr<Scope> scope(new Scope(settings->base_config())); | |
| 27 scope->SetProcessingImport(); | |
| 28 block->ExecuteBlockInScope(scope.get(), err); | |
| 29 if (err->has_error()) | |
| 30 return NULL; | |
| 31 scope->ClearProcessingImport(); | |
| 32 | |
| 33 return scope.release(); | |
| 34 } | |
| 35 | |
| 36 } // namesapce | |
| 37 | |
| 38 ImportManager::ImportManager() { | |
| 39 } | |
| 40 | |
| 41 ImportManager::~ImportManager() { | |
| 42 STLDeleteContainerPairSecondPointers(imports_.begin(), imports_.end()); | |
| 43 } | |
| 44 | |
| 45 bool ImportManager::DoImport(const SourceFile& file, | |
| 46 const ParseNode* node_for_err, | |
| 47 Scope* scope, | |
| 48 Err* err) { | |
| 49 // See if we have a cached import, but be careful to actually do the scope | |
| 50 // copying outside of the lock. | |
| 51 const Scope* imported_scope = NULL; | |
| 52 { | |
| 53 base::AutoLock lock(lock_); | |
| 54 ImportMap::const_iterator found = imports_.find(file); | |
| 55 if (found != imports_.end()) | |
| 56 imported_scope = found->second; | |
| 57 } | |
| 58 | |
| 59 if (!imported_scope) { | |
| 60 // Do a new import of the file. | |
| 61 imported_scope = UncachedImport(scope->settings(), file, | |
| 62 node_for_err, err); | |
| 63 if (!imported_scope) | |
| 64 return false; | |
| 65 | |
| 66 // We loaded the file outside the lock. This means that there could be a | |
| 67 // race and the file was already loaded on a background thread. Recover | |
| 68 // from this and use the existing one if that happens. | |
| 69 { | |
| 70 base::AutoLock lock(lock_); | |
| 71 ImportMap::const_iterator found = imports_.find(file); | |
| 72 if (found != imports_.end()) { | |
| 73 delete imported_scope; | |
| 74 imported_scope = found->second; | |
| 75 } else { | |
| 76 imports_[file] = imported_scope; | |
| 77 } | |
| 78 } | |
| 79 } | |
| 80 | |
| 81 return imported_scope->NonRecursiveMergeTo(scope, node_for_err, | |
| 82 "import", err); | |
| 83 } | |
| OLD | NEW |