[Extensions] Pull ModuleSystem::SourceMap into its own file

ModuleSystem::SourceMap contains a mapping from resource names to
resources, and is used for getting strings for our custom bindings.
It's a structure that will be useful in our C++ bindings, and its
already a little weird to have it be declared in the context of the
module system, so pull it out into its own file.

Also simplify the SourceMap object slightly to return a v8::String
directly and remove the helper method in ModuleSystem.

BUG=None

Review-Url: https://codereview.chromium.org/2560503003
Cr-Commit-Position: refs/heads/master@{#436738}
diff --git a/extensions/renderer/BUILD.gn b/extensions/renderer/BUILD.gn
index 21acb51..c17e69c 100644
--- a/extensions/renderer/BUILD.gn
+++ b/extensions/renderer/BUILD.gn
@@ -177,6 +177,7 @@
     "service_worker_request_sender.h",
     "set_icon_natives.cc",
     "set_icon_natives.h",
+    "source_map.h",
     "static_v8_external_one_byte_string_resource.cc",
     "static_v8_external_one_byte_string_resource.h",
     "test_features_native_handler.cc",
diff --git a/extensions/renderer/module_system.cc b/extensions/renderer/module_system.cc
index a8e3bdb..034291c 100644
--- a/extensions/renderer/module_system.cc
+++ b/extensions/renderer/module_system.cc
@@ -21,6 +21,7 @@
 #include "extensions/renderer/safe_builtins.h"
 #include "extensions/renderer/script_context.h"
 #include "extensions/renderer/script_context_set.h"
+#include "extensions/renderer/source_map.h"
 #include "extensions/renderer/v8_helpers.h"
 #include "gin/modules/module_registry.h"
 #include "third_party/WebKit/public/web/WebFrame.h"
@@ -545,14 +546,6 @@
                              base::Unretained(exception_handler_.get())));
 }
 
-v8::Local<v8::Value> ModuleSystem::GetSource(const std::string& module_name) {
-  v8::EscapableHandleScope handle_scope(GetIsolate());
-  if (!source_map_->Contains(module_name))
-    return v8::Undefined(GetIsolate());
-  return handle_scope.Escape(
-      v8::Local<v8::Value>(source_map_->GetSource(GetIsolate(), module_name)));
-}
-
 void ModuleSystem::RequireNative(
     const v8::FunctionCallbackInfo<v8::Value>& args) {
   CHECK_EQ(1, args.Length());
@@ -668,13 +661,13 @@
   v8::Local<v8::Context> v8_context = context()->v8_context();
   v8::Context::Scope context_scope(v8_context);
 
-  v8::Local<v8::Value> source(GetSource(module_name));
-  if (source.IsEmpty() || source->IsUndefined()) {
+  v8::Local<v8::String> source =
+      source_map_->GetSource(GetIsolate(), module_name);
+  if (source.IsEmpty()) {
     Fatal(context_, "No source for require(" + module_name + ")");
     return v8::Undefined(GetIsolate());
   }
-  v8::Local<v8::String> wrapped_source(
-      WrapSource(v8::Local<v8::String>::Cast(source)));
+  v8::Local<v8::String> wrapped_source(WrapSource(source));
   v8::Local<v8::String> v8_module_name;
   if (!ToV8String(GetIsolate(), module_name.c_str(), &v8_module_name)) {
     NOTREACHED() << "module_name is too long";
diff --git a/extensions/renderer/module_system.h b/extensions/renderer/module_system.h
index ab5aea23..9d7dbd27 100644
--- a/extensions/renderer/module_system.h
+++ b/extensions/renderer/module_system.h
@@ -22,6 +22,7 @@
 namespace extensions {
 
 class ScriptContext;
+class SourceMap;
 
 // A module system for JS similar to node.js' require() function.
 // Each module has three variables in the global scope:
@@ -42,14 +43,6 @@
 class ModuleSystem : public ObjectBackedNativeHandler,
                      public gin::ModuleRegistryObserver {
  public:
-  class SourceMap {
-   public:
-    virtual ~SourceMap() {}
-    virtual v8::Local<v8::Value> GetSource(v8::Isolate* isolate,
-                                           const std::string& name) const = 0;
-    virtual bool Contains(const std::string& name) const = 0;
-  };
-
   class ExceptionHandler {
    public:
     explicit ExceptionHandler(ScriptContext* context) : context_(context) {}
diff --git a/extensions/renderer/module_system_test.cc b/extensions/renderer/module_system_test.cc
index 87f6786..3ea5ce5 100644
--- a/extensions/renderer/module_system_test.cc
+++ b/extensions/renderer/module_system_test.cc
@@ -23,6 +23,7 @@
 #include "extensions/renderer/logging_native_handler.h"
 #include "extensions/renderer/object_backed_native_handler.h"
 #include "extensions/renderer/safe_builtins.h"
+#include "extensions/renderer/source_map.h"
 #include "extensions/renderer/utils_native_handler.h"
 #include "ui/base/resource/resource_bundle.h"
 
@@ -100,17 +101,16 @@
 };
 
 // Source map that operates on std::strings.
-class ModuleSystemTestEnvironment::StringSourceMap
-    : public ModuleSystem::SourceMap {
+class ModuleSystemTestEnvironment::StringSourceMap : public SourceMap {
  public:
   StringSourceMap() {}
   ~StringSourceMap() override {}
 
-  v8::Local<v8::Value> GetSource(v8::Isolate* isolate,
+  v8::Local<v8::String> GetSource(v8::Isolate* isolate,
                                  const std::string& name) const override {
     const auto& source_map_iter = source_map_.find(name);
     if (source_map_iter == source_map_.end())
-      return v8::Undefined(isolate);
+      return v8::Local<v8::String>();
     return v8::String::NewFromUtf8(isolate, source_map_iter->second.c_str());
   }
 
diff --git a/extensions/renderer/resource_bundle_source_map.cc b/extensions/renderer/resource_bundle_source_map.cc
index a260b54..073afe8 100644
--- a/extensions/renderer/resource_bundle_source_map.cc
+++ b/extensions/renderer/resource_bundle_source_map.cc
@@ -36,20 +36,20 @@
   resource_id_map_[name] = resource_id;
 }
 
-v8::Local<v8::Value> ResourceBundleSourceMap::GetSource(
+v8::Local<v8::String> ResourceBundleSourceMap::GetSource(
     v8::Isolate* isolate,
     const std::string& name) const {
   const auto& resource_id_iter = resource_id_map_.find(name);
   if (resource_id_iter == resource_id_map_.end()) {
     NOTREACHED() << "No module is registered with name \"" << name << "\"";
-    return v8::Undefined(isolate);
+    return v8::Local<v8::String>();
   }
   base::StringPiece resource =
       resource_bundle_->GetRawDataResource(resource_id_iter->second);
   if (resource.empty()) {
     NOTREACHED()
         << "Module resource registered as \"" << name << "\" not found";
-    return v8::Undefined(isolate);
+    return v8::Local<v8::String>();
   }
   return ConvertString(isolate, resource);
 }
diff --git a/extensions/renderer/resource_bundle_source_map.h b/extensions/renderer/resource_bundle_source_map.h
index 18ed4d2..42d3ba61 100644
--- a/extensions/renderer/resource_bundle_source_map.h
+++ b/extensions/renderer/resource_bundle_source_map.h
@@ -8,8 +8,8 @@
 #include <map>
 #include <string>
 
-#include "base/compiler_specific.h"
-#include "extensions/renderer/module_system.h"
+#include "base/macros.h"
+#include "extensions/renderer/source_map.h"
 #include "v8/include/v8.h"
 
 namespace ui {
@@ -18,13 +18,13 @@
 
 namespace extensions {
 
-class ResourceBundleSourceMap : public extensions::ModuleSystem::SourceMap {
+class ResourceBundleSourceMap : public SourceMap {
  public:
   explicit ResourceBundleSourceMap(const ui::ResourceBundle* resource_bundle);
   ~ResourceBundleSourceMap() override;
 
-  v8::Local<v8::Value> GetSource(v8::Isolate* isolate,
-                                 const std::string& name) const override;
+  v8::Local<v8::String> GetSource(v8::Isolate* isolate,
+                                  const std::string& name) const override;
   bool Contains(const std::string& name) const override;
 
   void RegisterSource(const std::string& name, int resource_id);
diff --git a/extensions/renderer/source_map.h b/extensions/renderer/source_map.h
new file mode 100644
index 0000000..6833181
--- /dev/null
+++ b/extensions/renderer/source_map.h
@@ -0,0 +1,29 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef EXTENSIONS_RENDERER_SOURCE_MAP_H_
+#define EXTENSIONS_RENDERER_SOURCE_MAP_H_
+
+#include <string>
+
+#include "v8/include/v8.h"
+
+namespace extensions {
+
+// A map storing resources associated with a given API or utility.
+class SourceMap {
+ public:
+  virtual ~SourceMap() {}
+
+  // Gets the source for the given resource name.
+  virtual v8::Local<v8::String> GetSource(v8::Isolate* isolate,
+                                          const std::string& name) const = 0;
+
+  // Returns true if the map contains an entry for the given |name|.
+  virtual bool Contains(const std::string& name) const = 0;
+};
+
+}  // namespace extensions
+
+#endif  // EXTENSIONS_RENDERER_SOURCE_MAP_H_