Cache source file type in SourceFile

This is in preparation for fixing bug 77.  Reduces the number of calls to
GetSourceFileType() from ~2 million to ~500 thousand when generating Chromium's
build files.

BUG=77
R=brettw

Change-Id: I044e5b5ebf41ce70769ae3818ea5989206f44453
Reviewed-on: https://gn-review.googlesource.com/c/gn/+/4960
Reviewed-by: Brett Wilson <brettw@google.com>
Commit-Queue: Brett Wilson <brettw@google.com>
diff --git a/build/gen.py b/build/gen.py
index 874ecba..97e5adb 100755
--- a/build/gen.py
+++ b/build/gen.py
@@ -520,7 +520,6 @@
         'tools/gn/setup.cc',
         'tools/gn/source_dir.cc',
         'tools/gn/source_file.cc',
-        'tools/gn/source_file_type.cc',
         'tools/gn/standard_out.cc',
         'tools/gn/string_utils.cc',
         'tools/gn/substitution_list.cc',
diff --git a/tools/gn/c_tool.h b/tools/gn/c_tool.h
index 129a733..07dfcbe 100644
--- a/tools/gn/c_tool.h
+++ b/tools/gn/c_tool.h
@@ -12,7 +12,6 @@
 #include "tools/gn/label.h"
 #include "tools/gn/label_ptr.h"
 #include "tools/gn/scope.h"
-#include "tools/gn/source_file_type.h"
 #include "tools/gn/substitution_list.h"
 #include "tools/gn/substitution_pattern.h"
 #include "tools/gn/tool.h"
diff --git a/tools/gn/compile_commands_writer.cc b/tools/gn/compile_commands_writer.cc
index e4a1a19..208952d 100644
--- a/tools/gn/compile_commands_writer.cc
+++ b/tools/gn/compile_commands_writer.cc
@@ -122,7 +122,7 @@
                   const CompileFlags& flags,
                   std::vector<OutputFile>& tool_outputs,
                   PathOutput& path_output,
-                  SourceFileType source_type,
+                  SourceFile::Type source_type,
                   const char* tool_name,
                   EscapeOptions opts,
                   std::string* compile_commands) {
@@ -144,16 +144,16 @@
     } else if (range.type == &CSubstitutionCFlags) {
       command_out << flags.cflags;
     } else if (range.type == &CSubstitutionCFlagsC) {
-      if (source_type == SOURCE_C)
+      if (source_type == SourceFile::SOURCE_C)
         command_out << flags.cflags_c;
     } else if (range.type == &CSubstitutionCFlagsCc) {
-      if (source_type == SOURCE_CPP)
+      if (source_type == SourceFile::SOURCE_CPP)
         command_out << flags.cflags_cc;
     } else if (range.type == &CSubstitutionCFlagsObjC) {
-      if (source_type == SOURCE_M)
+      if (source_type == SourceFile::SOURCE_M)
         command_out << flags.cflags_objc;
     } else if (range.type == &CSubstitutionCFlagsObjCc) {
-      if (source_type == SOURCE_MM)
+      if (source_type == SourceFile::SOURCE_MM)
         command_out << flags.cflags_objcc;
     } else if (range.type == &SubstitutionLabel ||
                range.type == &SubstitutionLabelName ||
@@ -222,9 +222,11 @@
     for (const auto& source : target->sources()) {
       // If this source is not a C/C++/ObjC/ObjC++ source (not header) file,
       // continue as it does not belong in the compilation database.
-      SourceFileType source_type = GetSourceFileType(source);
-      if (source_type != SOURCE_CPP && source_type != SOURCE_C &&
-          source_type != SOURCE_M && source_type != SOURCE_MM)
+      SourceFile::Type source_type = source.type();
+      if (source_type != SourceFile::SOURCE_CPP &&
+          source_type != SourceFile::SOURCE_C &&
+          source_type != SourceFile::SOURCE_M &&
+          source_type != SourceFile::SOURCE_MM)
         continue;
 
       const char* tool_name = Tool::kToolNone;
@@ -322,4 +324,4 @@
       VisitDeps(pair.ptr, visited);
     }
   }
-}
\ No newline at end of file
+}
diff --git a/tools/gn/general_tool.h b/tools/gn/general_tool.h
index b6e1af0..827a48d 100644
--- a/tools/gn/general_tool.h
+++ b/tools/gn/general_tool.h
@@ -11,7 +11,6 @@
 #include "base/macros.h"
 #include "tools/gn/label.h"
 #include "tools/gn/label_ptr.h"
-#include "tools/gn/source_file_type.h"
 #include "tools/gn/substitution_list.h"
 #include "tools/gn/substitution_pattern.h"
 #include "tools/gn/tool.h"
diff --git a/tools/gn/header_checker.cc b/tools/gn/header_checker.cc
index 8407bd0..dca7302 100644
--- a/tools/gn/header_checker.cc
+++ b/tools/gn/header_checker.cc
@@ -18,7 +18,6 @@
 #include "tools/gn/err.h"
 #include "tools/gn/filesystem_utils.h"
 #include "tools/gn/scheduler.h"
-#include "tools/gn/source_file_type.h"
 #include "tools/gn/target.h"
 #include "tools/gn/trace.h"
 #include "util/worker_pool.h"
@@ -152,9 +151,10 @@
 
   for (const auto& file : files) {
     // Only check C-like source files (RC files also have includes).
-    SourceFileType type = GetSourceFileType(file.first);
-    if (type != SOURCE_CPP && type != SOURCE_H && type != SOURCE_C &&
-        type != SOURCE_M && type != SOURCE_MM && type != SOURCE_RC)
+    SourceFile::Type type = file.first.type();
+    if (type != SourceFile::SOURCE_CPP && type != SourceFile::SOURCE_H &&
+        type != SourceFile::SOURCE_C && type != SourceFile::SOURCE_M &&
+        type != SourceFile::SOURCE_MM && type != SourceFile::SOURCE_RC)
       continue;
 
     if (!check_generated_) {
diff --git a/tools/gn/ninja_binary_target_writer.cc b/tools/gn/ninja_binary_target_writer.cc
index aca3a24..bf3ee35 100644
--- a/tools/gn/ninja_binary_target_writer.cc
+++ b/tools/gn/ninja_binary_target_writer.cc
@@ -23,22 +23,23 @@
 #include "tools/gn/ninja_utils.h"
 #include "tools/gn/scheduler.h"
 #include "tools/gn/settings.h"
-#include "tools/gn/source_file_type.h"
 #include "tools/gn/string_utils.h"
 #include "tools/gn/substitution_writer.h"
 #include "tools/gn/target.h"
 
 bool NinjaBinaryTargetWriter::SourceFileTypeSet::CSourceUsed() {
-  return Get(SOURCE_CPP) || Get(SOURCE_H) || Get(SOURCE_C) || Get(SOURCE_M) ||
-         Get(SOURCE_MM) || Get(SOURCE_RC) || Get(SOURCE_S);
+  return Get(SourceFile::SOURCE_CPP) || Get(SourceFile::SOURCE_H) ||
+         Get(SourceFile::SOURCE_C) || Get(SourceFile::SOURCE_M) ||
+         Get(SourceFile::SOURCE_MM) || Get(SourceFile::SOURCE_RC) ||
+         Get(SourceFile::SOURCE_S);
 }
 
 bool NinjaBinaryTargetWriter::SourceFileTypeSet::RustSourceUsed() {
-  return Get(SOURCE_RS);
+  return Get(SourceFile::SOURCE_RS);
 }
 
 bool NinjaBinaryTargetWriter::SourceFileTypeSet::GoSourceUsed() {
-  return Get(SOURCE_GO);
+  return Get(SourceFile::SOURCE_GO);
 }
 
 NinjaBinaryTargetWriter::NinjaBinaryTargetWriter(const Target* target,
@@ -49,10 +50,6 @@
 NinjaBinaryTargetWriter::~NinjaBinaryTargetWriter() = default;
 
 void NinjaBinaryTargetWriter::Run() {
-  SourceFileTypeSet used_types;
-  for (const auto& source : target_->sources())
-    used_types.Set(GetSourceFileType(source));
-
   NinjaCBinaryTargetWriter writer(target_, out_);
   writer.Run();
 }
diff --git a/tools/gn/ninja_binary_target_writer.h b/tools/gn/ninja_binary_target_writer.h
index 1db9d81..24d7ef1 100644
--- a/tools/gn/ninja_binary_target_writer.h
+++ b/tools/gn/ninja_binary_target_writer.h
@@ -23,11 +23,12 @@
   class SourceFileTypeSet {
    public:
     SourceFileTypeSet() {
-      memset(flags_, 0, sizeof(bool) * static_cast<int>(SOURCE_NUMTYPES));
+      memset(flags_, 0,
+             sizeof(bool) * static_cast<int>(SourceFile::SOURCE_NUMTYPES));
     }
 
-    void Set(SourceFileType type) { flags_[static_cast<int>(type)] = true; }
-    bool Get(SourceFileType type) const {
+    void Set(SourceFile::Type type) { flags_[static_cast<int>(type)] = true; }
+    bool Get(SourceFile::Type type) const {
       return flags_[static_cast<int>(type)];
     }
 
@@ -36,7 +37,7 @@
     bool GoSourceUsed();
 
    private:
-    bool flags_[static_cast<int>(SOURCE_NUMTYPES)];
+    bool flags_[static_cast<int>(SourceFile::SOURCE_NUMTYPES)];
   };
 
   NinjaBinaryTargetWriter(const Target* target, std::ostream& out);
diff --git a/tools/gn/ninja_c_binary_target_writer.cc b/tools/gn/ninja_c_binary_target_writer.cc
index f6ffd15..4e8217b 100644
--- a/tools/gn/ninja_c_binary_target_writer.cc
+++ b/tools/gn/ninja_c_binary_target_writer.cc
@@ -24,7 +24,6 @@
 #include "tools/gn/ninja_utils.h"
 #include "tools/gn/scheduler.h"
 #include "tools/gn/settings.h"
-#include "tools/gn/source_file_type.h"
 #include "tools/gn/string_utils.h"
 #include "tools/gn/substitution_writer.h"
 #include "tools/gn/target.h"
@@ -67,27 +66,27 @@
     if (source_set->GetOutputFilesForSource(source, &tool_name, &tool_outputs))
       obj_files->push_back(tool_outputs[0]);
 
-    used_types.Set(GetSourceFileType(source));
+    used_types.Set(source.type());
   }
 
   // Add MSVC precompiled header object files. GCC .gch files are not object
   // files so they are omitted.
   if (source_set->config_values().has_precompiled_headers()) {
-    if (used_types.Get(SOURCE_C)) {
+    if (used_types.Get(SourceFile::SOURCE_C)) {
       const CTool* tool = source_set->toolchain()->GetToolAsC(CTool::kCToolCc);
       if (tool && tool->precompiled_header_type() == CTool::PCH_MSVC) {
         GetPCHOutputFiles(source_set, CTool::kCToolCc, &tool_outputs);
         obj_files->Append(tool_outputs.begin(), tool_outputs.end());
       }
     }
-    if (used_types.Get(SOURCE_CPP)) {
+    if (used_types.Get(SourceFile::SOURCE_CPP)) {
       const CTool* tool = source_set->toolchain()->GetToolAsC(CTool::kCToolCxx);
       if (tool && tool->precompiled_header_type() == CTool::PCH_MSVC) {
         GetPCHOutputFiles(source_set, CTool::kCToolCxx, &tool_outputs);
         obj_files->Append(tool_outputs.begin(), tool_outputs.end());
       }
     }
-    if (used_types.Get(SOURCE_M)) {
+    if (used_types.Get(SourceFile::SOURCE_M)) {
       const CTool* tool =
           source_set->toolchain()->GetToolAsC(CTool::kCToolObjC);
       if (tool && tool->precompiled_header_type() == CTool::PCH_MSVC) {
@@ -95,7 +94,7 @@
         obj_files->Append(tool_outputs.begin(), tool_outputs.end());
       }
     }
-    if (used_types.Get(SOURCE_MM)) {
+    if (used_types.Get(SourceFile::SOURCE_MM)) {
       const CTool* tool =
           source_set->toolchain()->GetToolAsC(CTool::kCToolObjCxx);
       if (tool && tool->precompiled_header_type() == CTool::PCH_MSVC) {
@@ -119,7 +118,7 @@
   // Figure out what source types are needed.
   SourceFileTypeSet used_types;
   for (const auto& source : target_->sources())
-    used_types.Set(GetSourceFileType(source));
+    used_types.Set(source.type());
 
   WriteCompilerVars(used_types);
 
@@ -235,31 +234,34 @@
       target_->config_values().has_precompiled_headers();
 
   EscapeOptions opts = GetFlagOptions();
-  if (used_types.Get(SOURCE_S) || used_types.Get(SOURCE_ASM)) {
+  if (used_types.Get(SourceFile::SOURCE_S) ||
+      used_types.Get(SourceFile::SOURCE_ASM)) {
     WriteOneFlag(target_, &CSubstitutionAsmFlags, false, Tool::kToolNone,
                  &ConfigValues::asmflags, opts, path_output_, out_);
   }
-  if (used_types.Get(SOURCE_C) || used_types.Get(SOURCE_CPP) ||
-      used_types.Get(SOURCE_M) || used_types.Get(SOURCE_MM)) {
+  if (used_types.Get(SourceFile::SOURCE_C) ||
+      used_types.Get(SourceFile::SOURCE_CPP) ||
+      used_types.Get(SourceFile::SOURCE_M) ||
+      used_types.Get(SourceFile::SOURCE_MM)) {
     WriteOneFlag(target_, &CSubstitutionCFlags, false, Tool::kToolNone,
                  &ConfigValues::cflags, opts, path_output_, out_);
   }
-  if (used_types.Get(SOURCE_C)) {
+  if (used_types.Get(SourceFile::SOURCE_C)) {
     WriteOneFlag(target_, &CSubstitutionCFlagsC, has_precompiled_headers,
                  CTool::kCToolCc, &ConfigValues::cflags_c, opts, path_output_,
                  out_);
   }
-  if (used_types.Get(SOURCE_CPP)) {
+  if (used_types.Get(SourceFile::SOURCE_CPP)) {
     WriteOneFlag(target_, &CSubstitutionCFlagsCc, has_precompiled_headers,
                  CTool::kCToolCxx, &ConfigValues::cflags_cc, opts, path_output_,
                  out_);
   }
-  if (used_types.Get(SOURCE_M)) {
+  if (used_types.Get(SourceFile::SOURCE_M)) {
     WriteOneFlag(target_, &CSubstitutionCFlagsObjC, has_precompiled_headers,
                  CTool::kCToolObjC, &ConfigValues::cflags_objc, opts,
                  path_output_, out_);
   }
-  if (used_types.Get(SOURCE_MM)) {
+  if (used_types.Get(SourceFile::SOURCE_MM)) {
     WriteOneFlag(target_, &CSubstitutionCFlagsObjCc, has_precompiled_headers,
                  CTool::kCToolObjCxx, &ConfigValues::cflags_objcc, opts,
                  path_output_, out_);
@@ -319,14 +321,14 @@
 
   const CTool* tool_c = target_->toolchain()->GetToolAsC(CTool::kCToolCc);
   if (tool_c && tool_c->precompiled_header_type() != CTool::PCH_NONE &&
-      used_types.Get(SOURCE_C)) {
+      used_types.Get(SourceFile::SOURCE_C)) {
     WritePCHCommand(&CSubstitutionCFlagsC, CTool::kCToolCc,
                     tool_c->precompiled_header_type(), input_dep,
                     order_only_deps, object_files, other_files);
   }
   const CTool* tool_cxx = target_->toolchain()->GetToolAsC(CTool::kCToolCxx);
   if (tool_cxx && tool_cxx->precompiled_header_type() != CTool::PCH_NONE &&
-      used_types.Get(SOURCE_CPP)) {
+      used_types.Get(SourceFile::SOURCE_CPP)) {
     WritePCHCommand(&CSubstitutionCFlagsCc, CTool::kCToolCxx,
                     tool_cxx->precompiled_header_type(), input_dep,
                     order_only_deps, object_files, other_files);
@@ -334,7 +336,7 @@
 
   const CTool* tool_objc = target_->toolchain()->GetToolAsC(CTool::kCToolObjC);
   if (tool_objc && tool_objc->precompiled_header_type() == CTool::PCH_GCC &&
-      used_types.Get(SOURCE_M)) {
+      used_types.Get(SourceFile::SOURCE_M)) {
     WritePCHCommand(&CSubstitutionCFlagsObjC, CTool::kCToolObjC,
                     tool_objc->precompiled_header_type(), input_dep,
                     order_only_deps, object_files, other_files);
@@ -343,7 +345,7 @@
   const CTool* tool_objcxx =
       target_->toolchain()->GetToolAsC(CTool::kCToolObjCxx);
   if (tool_objcxx && tool_objcxx->precompiled_header_type() == CTool::PCH_GCC &&
-      used_types.Get(SOURCE_MM)) {
+      used_types.Get(SourceFile::SOURCE_MM)) {
     WritePCHCommand(&CSubstitutionCFlagsObjCc, CTool::kCToolObjCxx,
                     tool_objcxx->precompiled_header_type(), input_dep,
                     order_only_deps, object_files, other_files);
@@ -476,7 +478,7 @@
     deps.resize(0);
     const char* tool_name = Tool::kToolNone;
     if (!target_->GetOutputFilesForSource(source, &tool_name, &tool_outputs)) {
-      if (GetSourceFileType(source) == SOURCE_DEF)
+      if (source.type() == SourceFile::SOURCE_DEF)
         other_files->push_back(source);
       continue;  // No output for this source.
     }
@@ -597,7 +599,7 @@
   const SourceFile* optional_def_file = nullptr;
   if (!other_files.empty()) {
     for (const SourceFile& src_file : other_files) {
-      if (GetSourceFileType(src_file) == SOURCE_DEF) {
+      if (src_file.type() == SourceFile::SOURCE_DEF) {
         optional_def_file = &src_file;
         implicit_deps.push_back(
             OutputFile(settings_->build_settings(), src_file));
diff --git a/tools/gn/source_file.cc b/tools/gn/source_file.cc
index 79c6eb0..7c860d4 100644
--- a/tools/gn/source_file.cc
+++ b/tools/gn/source_file.cc
@@ -21,18 +21,48 @@
   DCHECK(!EndsWithSlash(s)) << s;
 }
 
+SourceFile::Type GetSourceFileType(const std::string& file) {
+  base::StringPiece extension = FindExtension(&file);
+  if (extension == "cc" || extension == "cpp" || extension == "cxx")
+    return SourceFile::SOURCE_CPP;
+  if (extension == "h" || extension == "hpp" || extension == "hxx" ||
+      extension == "hh" || extension == "inc")
+    return SourceFile::SOURCE_H;
+  if (extension == "c")
+    return SourceFile::SOURCE_C;
+  if (extension == "m")
+    return SourceFile::SOURCE_M;
+  if (extension == "mm")
+    return SourceFile::SOURCE_MM;
+  if (extension == "rc")
+    return SourceFile::SOURCE_RC;
+  if (extension == "S" || extension == "s" || extension == "asm")
+    return SourceFile::SOURCE_S;
+  if (extension == "o" || extension == "obj")
+    return SourceFile::SOURCE_O;
+  if (extension == "def")
+    return SourceFile::SOURCE_DEF;
+  if (extension == "rs")
+    return SourceFile::SOURCE_RS;
+  if (extension == "go")
+    return SourceFile::SOURCE_GO;
+
+  return SourceFile::SOURCE_UNKNOWN;
+}
+
 }  // namespace
 
-SourceFile::SourceFile() = default;
+SourceFile::SourceFile() : type_(SOURCE_UNKNOWN) {}
 
 SourceFile::SourceFile(const base::StringPiece& p)
-    : value_(p.data(), p.size()) {
+    : value_(p.data(), p.size()), type_(GetSourceFileType(value_)) {
   DCHECK(!value_.empty());
   AssertValueSourceFileString(value_);
   NormalizePath(&value_);
 }
 
-SourceFile::SourceFile(SwapIn, std::string* value) {
+SourceFile::SourceFile(SwapIn, std::string* value)
+    : type_(GetSourceFileType(*value)) {
   value_.swap(*value);
   DCHECK(!value_.empty());
   AssertValueSourceFileString(value_);
diff --git a/tools/gn/source_file.h b/tools/gn/source_file.h
index f033987..bcf5f42 100644
--- a/tools/gn/source_file.h
+++ b/tools/gn/source_file.h
@@ -20,6 +20,28 @@
 // ends in one.
 class SourceFile {
  public:
+  // This should be sequential integers starting from 0 so they can be used as
+  // array indices.
+  enum Type {
+    SOURCE_UNKNOWN = 0,
+    SOURCE_ASM,
+    SOURCE_C,
+    SOURCE_CPP,
+    SOURCE_H,
+    SOURCE_M,
+    SOURCE_MM,
+    SOURCE_S,
+    SOURCE_RC,
+    SOURCE_O,  // Object files can be inputs, too. Also counts .obj.
+    SOURCE_DEF,
+
+    SOURCE_RS,
+    SOURCE_GO,
+
+    // Must be last.
+    SOURCE_NUMTYPES,
+  };
+
   enum SwapIn { SWAP_IN };
 
   SourceFile();
@@ -36,6 +58,7 @@
 
   bool is_null() const { return value_.empty(); }
   const std::string& value() const { return value_; }
+  Type type() const { return type_; }
 
   // Returns everything after the last slash.
   std::string GetName() const;
@@ -80,6 +103,7 @@
   friend class SourceDir;
 
   std::string value_;
+  Type type_;
 
   // Copy & assign supported.
 };
diff --git a/tools/gn/source_file_type.cc b/tools/gn/source_file_type.cc
deleted file mode 100644
index fde1cca..0000000
--- a/tools/gn/source_file_type.cc
+++ /dev/null
@@ -1,37 +0,0 @@
-// 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.
-
-#include "tools/gn/source_file_type.h"
-
-#include "tools/gn/filesystem_utils.h"
-#include "tools/gn/source_file.h"
-
-SourceFileType GetSourceFileType(const SourceFile& file) {
-  base::StringPiece extension = FindExtension(&file.value());
-  if (extension == "cc" || extension == "cpp" || extension == "cxx")
-    return SOURCE_CPP;
-  if (extension == "h" || extension == "hpp" || extension == "hxx" ||
-      extension == "hh")
-    return SOURCE_H;
-  if (extension == "c")
-    return SOURCE_C;
-  if (extension == "m")
-    return SOURCE_M;
-  if (extension == "mm")
-    return SOURCE_MM;
-  if (extension == "rc")
-    return SOURCE_RC;
-  if (extension == "S" || extension == "s" || extension == "asm")
-    return SOURCE_S;
-  if (extension == "o" || extension == "obj")
-    return SOURCE_O;
-  if (extension == "def")
-    return SOURCE_DEF;
-  if (extension == "rs")
-    return SOURCE_RS;
-  if (extension == "go")
-    return SOURCE_GO;
-
-  return SOURCE_UNKNOWN;
-}
diff --git a/tools/gn/source_file_type.h b/tools/gn/source_file_type.h
deleted file mode 100644
index d405497..0000000
--- a/tools/gn/source_file_type.h
+++ /dev/null
@@ -1,34 +0,0 @@
-// 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 TOOLS_GN_SOURCE_FILE_TYPE_H_
-#define TOOLS_GN_SOURCE_FILE_TYPE_H_
-
-class SourceFile;
-
-// This should be sequential integers starting from 0 so they can be used as
-// array indices.
-enum SourceFileType {
-  SOURCE_UNKNOWN = 0,
-  SOURCE_ASM,
-  SOURCE_C,
-  SOURCE_CPP,
-  SOURCE_H,
-  SOURCE_M,
-  SOURCE_MM,
-  SOURCE_S,
-  SOURCE_RC,
-  SOURCE_O,  // Object files can be inputs, too. Also counts .obj.
-  SOURCE_DEF,
-
-  SOURCE_RS,
-  SOURCE_GO,
-
-  // Must be last.
-  SOURCE_NUMTYPES,
-};
-
-SourceFileType GetSourceFileType(const SourceFile& file);
-
-#endif  // TOOLS_GN_SOURCE_FILE_TYPE_H_
diff --git a/tools/gn/target.cc b/tools/gn/target.cc
index 6272b44..1afd22b 100644
--- a/tools/gn/target.cc
+++ b/tools/gn/target.cc
@@ -16,7 +16,6 @@
 #include "tools/gn/filesystem_utils.h"
 #include "tools/gn/functions.h"
 #include "tools/gn/scheduler.h"
-#include "tools/gn/source_file_type.h"
 #include "tools/gn/substitution_writer.h"
 #include "tools/gn/tool.h"
 #include "tools/gn/toolchain.h"
@@ -487,10 +486,10 @@
   outputs->clear();
   *computed_tool_type = Tool::kToolNone;
 
-  SourceFileType file_type = GetSourceFileType(source);
-  if (file_type == SOURCE_UNKNOWN)
+  SourceFile::Type file_type = source.type();
+  if (file_type == SourceFile::SOURCE_UNKNOWN)
     return false;
-  if (file_type == SOURCE_O) {
+  if (file_type == SourceFile::SOURCE_O) {
     // Object files just get passed to the output and not compiled.
     outputs->push_back(OutputFile(settings()->build_settings(), source));
     return true;
diff --git a/tools/gn/tool.cc b/tools/gn/tool.cc
index 7a06b03..b040ac2 100644
--- a/tools/gn/tool.cc
+++ b/tools/gn/tool.cc
@@ -261,27 +261,27 @@
 }
 
 // static
-const char* Tool::GetToolTypeForSourceType(SourceFileType type) {
+const char* Tool::GetToolTypeForSourceType(SourceFile::Type type) {
   switch (type) {
-    case SOURCE_C:
+    case SourceFile::SOURCE_C:
       return CTool::kCToolCc;
-    case SOURCE_CPP:
+    case SourceFile::SOURCE_CPP:
       return CTool::kCToolCxx;
-    case SOURCE_M:
+    case SourceFile::SOURCE_M:
       return CTool::kCToolObjC;
-    case SOURCE_MM:
+    case SourceFile::SOURCE_MM:
       return CTool::kCToolObjCxx;
-    case SOURCE_ASM:
-    case SOURCE_S:
+    case SourceFile::SOURCE_ASM:
+    case SourceFile::SOURCE_S:
       return CTool::kCToolAsm;
-    case SOURCE_RC:
+    case SourceFile::SOURCE_RC:
       return CTool::kCToolRc;
-    case SOURCE_UNKNOWN:
-    case SOURCE_H:
-    case SOURCE_O:
-    case SOURCE_DEF:
-    case SOURCE_GO:
-    case SOURCE_RS:
+    case SourceFile::SOURCE_UNKNOWN:
+    case SourceFile::SOURCE_H:
+    case SourceFile::SOURCE_O:
+    case SourceFile::SOURCE_DEF:
+    case SourceFile::SOURCE_GO:
+    case SourceFile::SOURCE_RS:
       return kToolNone;
     default:
       NOTREACHED();
diff --git a/tools/gn/tool.h b/tools/gn/tool.h
index ec2eb94..a6f177d 100644
--- a/tools/gn/tool.h
+++ b/tools/gn/tool.h
@@ -12,7 +12,7 @@
 #include "tools/gn/label.h"
 #include "tools/gn/label_ptr.h"
 #include "tools/gn/scope.h"
-#include "tools/gn/source_file_type.h"
+#include "tools/gn/source_file.h"
 #include "tools/gn/substitution_list.h"
 #include "tools/gn/substitution_pattern.h"
 
@@ -171,7 +171,7 @@
                                           Toolchain* toolchain,
                                           Err* err);
 
-  static const char* GetToolTypeForSourceType(SourceFileType type);
+  static const char* GetToolTypeForSourceType(SourceFile::Type type);
   static const char* GetToolTypeForTargetFinalOutput(const Target* target);
 
  protected:
diff --git a/tools/gn/toolchain.cc b/tools/gn/toolchain.cc
index b718052..0d6cbaf 100644
--- a/tools/gn/toolchain.cc
+++ b/tools/gn/toolchain.cc
@@ -88,16 +88,16 @@
   setup_complete_ = true;
 }
 
-const Tool* Toolchain::GetToolForSourceType(SourceFileType type) const {
+const Tool* Toolchain::GetToolForSourceType(SourceFile::Type type) const {
   return GetTool(Tool::GetToolTypeForSourceType(type));
 }
 
-const CTool* Toolchain::GetToolForSourceTypeAsC(SourceFileType type) const {
+const CTool* Toolchain::GetToolForSourceTypeAsC(SourceFile::Type type) const {
   return GetToolAsC(Tool::GetToolTypeForSourceType(type));
 }
 
 const GeneralTool* Toolchain::GetToolForSourceTypeAsGeneral(
-    SourceFileType type) const {
+    SourceFile::Type type) const {
   return GetToolAsGeneral(Tool::GetToolTypeForSourceType(type));
 }
 
diff --git a/tools/gn/toolchain.h b/tools/gn/toolchain.h
index e36475d..cc93de5 100644
--- a/tools/gn/toolchain.h
+++ b/tools/gn/toolchain.h
@@ -12,7 +12,6 @@
 #include "tools/gn/item.h"
 #include "tools/gn/label_ptr.h"
 #include "tools/gn/scope.h"
-#include "tools/gn/source_file_type.h"
 #include "tools/gn/substitution_type.h"
 #include "tools/gn/tool.h"
 #include "tools/gn/value.h"
@@ -88,9 +87,9 @@
   }
 
   // Returns the tool for compiling the given source file type.
-  const Tool* GetToolForSourceType(SourceFileType type) const;
-  const CTool* GetToolForSourceTypeAsC(SourceFileType type) const;
-  const GeneralTool* GetToolForSourceTypeAsGeneral(SourceFileType type) const;
+  const Tool* GetToolForSourceType(SourceFile::Type type) const;
+  const CTool* GetToolForSourceTypeAsC(SourceFile::Type type) const;
+  const GeneralTool* GetToolForSourceTypeAsGeneral(SourceFile::Type type) const;
 
   // Returns the tool that produces the final output for the given target type.
   // This isn't necessarily the tool you would expect. For copy target, this
diff --git a/tools/gn/visual_studio_writer.cc b/tools/gn/visual_studio_writer.cc
index f804b44..9dbd4b3 100644
--- a/tools/gn/visual_studio_writer.cc
+++ b/tools/gn/visual_studio_writer.cc
@@ -24,7 +24,6 @@
 #include "tools/gn/label_pattern.h"
 #include "tools/gn/parse_tree.h"
 #include "tools/gn/path_output.h"
-#include "tools/gn/source_file_type.h"
 #include "tools/gn/standard_out.h"
 #include "tools/gn/target.h"
 #include "tools/gn/variables.h"