mirror of
				https://github.com/MaskRay/ccls.git
				synced 2025-10-31 12:42:34 +00:00 
			
		
		
		
	A bit more code cleanup in project.cc
This commit is contained in:
		
							parent
							
								
									a96be1d6e5
								
							
						
					
					
						commit
						bd8582e718
					
				| @ -26,9 +26,11 @@ MAKE_REFLECT_STRUCT(CompileCommandsEntry, directory, file, command, args); | |||||||
| 
 | 
 | ||||||
| namespace { | namespace { | ||||||
| 
 | 
 | ||||||
| struct IncludeDirectories { | struct ProjectConfig { | ||||||
|   std::unordered_set<std::string> quote_dirs; |   std::unordered_set<std::string> quote_dirs; | ||||||
|   std::unordered_set<std::string> angle_dirs; |   std::unordered_set<std::string> angle_dirs; | ||||||
|  |   std::vector<std::string> extra_flags; | ||||||
|  |   std::string project_dir; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| static const char* kBlacklistMulti[] = {"-MF", "-Xclang"}; | static const char* kBlacklistMulti[] = {"-MF", "-Xclang"}; | ||||||
| @ -88,8 +90,7 @@ bool IsCFile(const std::string& path) { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| Project::Entry GetCompilationEntryFromCompileCommandEntry( | Project::Entry GetCompilationEntryFromCompileCommandEntry( | ||||||
|     IncludeDirectories* includes, |     ProjectConfig* config, | ||||||
|     const std::vector<std::string>& extra_flags, |  | ||||||
|     const CompileCommandsEntry& entry) { |     const CompileCommandsEntry& entry) { | ||||||
|   Project::Entry result; |   Project::Entry result; | ||||||
|   result.filename = NormalizePath(entry.file); |   result.filename = NormalizePath(entry.file); | ||||||
| @ -98,7 +99,7 @@ Project::Entry GetCompilationEntryFromCompileCommandEntry( | |||||||
|   bool add_next_flag_quote = false; |   bool add_next_flag_quote = false; | ||||||
|   bool add_next_flag_angle = false; |   bool add_next_flag_angle = false; | ||||||
| 
 | 
 | ||||||
|   result.args.reserve(entry.args.size() + extra_flags.size()); |   result.args.reserve(entry.args.size() + config->extra_flags.size()); | ||||||
|   for (size_t i = 0; i < entry.args.size(); ++i) { |   for (size_t i = 0; i < entry.args.size(); ++i) { | ||||||
|     std::string arg = entry.args[i]; |     std::string arg = entry.args[i]; | ||||||
| 
 | 
 | ||||||
| @ -122,9 +123,9 @@ Project::Entry GetCompilationEntryFromCompileCommandEntry( | |||||||
|       make_next_flag_absolute = false; |       make_next_flag_absolute = false; | ||||||
| 
 | 
 | ||||||
|       if (add_next_flag_quote) |       if (add_next_flag_quote) | ||||||
|         includes->quote_dirs.insert(arg); |         config->quote_dirs.insert(arg); | ||||||
|       if (add_next_flag_angle) |       if (add_next_flag_angle) | ||||||
|         includes->angle_dirs.insert(arg); |         config->angle_dirs.insert(arg); | ||||||
|       add_next_flag_quote = false; |       add_next_flag_quote = false; | ||||||
|       add_next_flag_angle = false; |       add_next_flag_angle = false; | ||||||
|     } |     } | ||||||
| @ -148,9 +149,9 @@ Project::Entry GetCompilationEntryFromCompileCommandEntry( | |||||||
|           arg = flag_type + path; |           arg = flag_type + path; | ||||||
|         } |         } | ||||||
|         if (ShouldAddToQuoteIncludes(arg)) |         if (ShouldAddToQuoteIncludes(arg)) | ||||||
|           includes->quote_dirs.insert(path); |           config->quote_dirs.insert(path); | ||||||
|         if (ShouldAddToAngleIncludes(arg)) |         if (ShouldAddToAngleIncludes(arg)) | ||||||
|           includes->angle_dirs.insert(path); |           config->angle_dirs.insert(path); | ||||||
|         break; |         break; | ||||||
|       } |       } | ||||||
|     } |     } | ||||||
| @ -159,7 +160,7 @@ Project::Entry GetCompilationEntryFromCompileCommandEntry( | |||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   // We don't do any special processing on user-given extra flags.
 |   // We don't do any special processing on user-given extra flags.
 | ||||||
|   for (const auto& flag : extra_flags) |   for (const auto& flag : config->extra_flags) | ||||||
|     result.args.push_back(flag); |     result.args.push_back(flag); | ||||||
| 
 | 
 | ||||||
|   // Clang does not have good hueristics for determining source language, we
 |   // Clang does not have good hueristics for determining source language, we
 | ||||||
| @ -180,45 +181,13 @@ Project::Entry GetCompilationEntryFromCompileCommandEntry( | |||||||
|   return result; |   return result; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /* TODO: Fix this function, it may be way faster than libclang's implementation.
 |  | ||||||
| std::vector<Project::Entry> LoadFromCompileCommandsJson( |  | ||||||
|     std::unordered_set<std::string>& quote_includes, |  | ||||||
| std::unordered_set<std::string>& angle_includes, const std::vector<std::string>& |  | ||||||
| extra_flags, const std::string& project_directory) { |  | ||||||
| 
 |  | ||||||
|   optional<std::string> compile_commands_content = ReadContent(project_directory |  | ||||||
| + "/compile_commands.json"); if (!compile_commands_content) return {}; |  | ||||||
| 
 |  | ||||||
|   rapidjson::Document reader; |  | ||||||
|   reader.Parse(compile_commands_content->c_str()); |  | ||||||
|   if (reader.HasParseError()) |  | ||||||
|     return {}; |  | ||||||
| 
 |  | ||||||
|   std::vector<CompileCommandsEntry> entries; |  | ||||||
|   Reflect(reader, entries); |  | ||||||
| 
 |  | ||||||
|   std::vector<Project::Entry> result; |  | ||||||
|   result.reserve(entries.size()); |  | ||||||
|   for (auto& entry : entries) { |  | ||||||
|     if (entry.args.empty() && !entry.command.empty()) |  | ||||||
|       entry.args = SplitString(entry.command, " "); |  | ||||||
| 
 |  | ||||||
|     result.push_back(GetCompilationEntryFromCompileCommandEntry(quote_includes, |  | ||||||
| angle_includes, extra_flags, entry)); |  | ||||||
|   } |  | ||||||
|   return result; |  | ||||||
| } |  | ||||||
| */ |  | ||||||
| 
 |  | ||||||
| std::vector<Project::Entry> LoadFromDirectoryListing( | std::vector<Project::Entry> LoadFromDirectoryListing( | ||||||
|     IncludeDirectories* includes, |     ProjectConfig* config) { | ||||||
|     const std::vector<std::string>& extra_flags, |  | ||||||
|     const std::string& project_directory) { |  | ||||||
|   std::vector<Project::Entry> result; |   std::vector<Project::Entry> result; | ||||||
| 
 | 
 | ||||||
|   std::vector<std::string> args; |   std::vector<std::string> args; | ||||||
|   std::cerr << "Using arguments: "; |   std::cerr << "Using arguments: "; | ||||||
|   for (const std::string& line : ReadLines(project_directory + "/clang_args")) { |   for (const std::string& line : ReadLines(config->project_dir + "/clang_args")) { | ||||||
|     if (line.empty() || StartsWith(line, "#")) |     if (line.empty() || StartsWith(line, "#")) | ||||||
|       continue; |       continue; | ||||||
|     if (!args.empty()) |     if (!args.empty()) | ||||||
| @ -229,7 +198,7 @@ std::vector<Project::Entry> LoadFromDirectoryListing( | |||||||
|   std::cerr << std::endl; |   std::cerr << std::endl; | ||||||
| 
 | 
 | ||||||
|   std::vector<std::string> files = GetFilesInFolder( |   std::vector<std::string> files = GetFilesInFolder( | ||||||
|       project_directory, true /*recursive*/, true /*add_folder_to_path*/); |       config->project_dir, true /*recursive*/, true /*add_folder_to_path*/); | ||||||
|   for (const std::string& file : files) { |   for (const std::string& file : files) { | ||||||
|     if (EndsWith(file, ".cc") || EndsWith(file, ".cpp") || |     if (EndsWith(file, ".cc") || EndsWith(file, ".cpp") || | ||||||
|         EndsWith(file, ".c")) { |         EndsWith(file, ".c")) { | ||||||
| @ -237,7 +206,7 @@ std::vector<Project::Entry> LoadFromDirectoryListing( | |||||||
|       e.file = NormalizePath(file); |       e.file = NormalizePath(file); | ||||||
|       e.args = args; |       e.args = args; | ||||||
|       result.push_back( |       result.push_back( | ||||||
|           GetCompilationEntryFromCompileCommandEntry(includes, extra_flags, e)); |           GetCompilationEntryFromCompileCommandEntry(config, e)); | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
| @ -245,21 +214,17 @@ std::vector<Project::Entry> LoadFromDirectoryListing( | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| std::vector<Project::Entry> LoadCompilationEntriesFromDirectory( | std::vector<Project::Entry> LoadCompilationEntriesFromDirectory( | ||||||
|     IncludeDirectories* includes, |     ProjectConfig* config) { | ||||||
|     const std::vector<std::string>& extra_flags, |  | ||||||
|     const std::string& project_directory) { |  | ||||||
|   // TODO: Figure out if this function or the clang one is faster.
 |  | ||||||
|   // return LoadFromCompileCommandsJson(extra_flags, project_directory);
 |  | ||||||
| 
 | 
 | ||||||
|   std::cerr << "Trying to load compile_commands.json" << std::endl; |   // Try to load compile_commands.json, but fallback to a project listing.
 | ||||||
|  |   LOG_S(INFO) << "Trying to load compile_commands.json"; | ||||||
|   CXCompilationDatabase_Error cx_db_load_error; |   CXCompilationDatabase_Error cx_db_load_error; | ||||||
|   CXCompilationDatabase cx_db = clang_CompilationDatabase_fromDirectory( |   CXCompilationDatabase cx_db = clang_CompilationDatabase_fromDirectory( | ||||||
|       project_directory.c_str(), &cx_db_load_error); |       config->project_dir.c_str(), &cx_db_load_error); | ||||||
|   if (cx_db_load_error == CXCompilationDatabase_CanNotLoadDatabase) { |   if (cx_db_load_error == CXCompilationDatabase_CanNotLoadDatabase) { | ||||||
|     std::cerr << "Unable to load compile_commands.json located at \"" |     LOG_S(INFO) << "Unable to load compile_commands.json located at \"" | ||||||
|               << project_directory << "\"; using directory listing instead." |               << config->project_dir << "\"; using directory listing instead."; | ||||||
|               << std::endl; |     return LoadFromDirectoryListing(config); | ||||||
|     return LoadFromDirectoryListing(includes, extra_flags, project_directory); |  | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   CXCompileCommands cx_commands = |   CXCompileCommands cx_commands = | ||||||
| @ -288,7 +253,7 @@ std::vector<Project::Entry> LoadCompilationEntriesFromDirectory( | |||||||
|           clang::ToString(clang_CompileCommand_getArg(cx_command, j))); |           clang::ToString(clang_CompileCommand_getArg(cx_command, j))); | ||||||
| 
 | 
 | ||||||
|     result.push_back(GetCompilationEntryFromCompileCommandEntry( |     result.push_back(GetCompilationEntryFromCompileCommandEntry( | ||||||
|         includes, extra_flags, entry)); |         config, entry)); | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   clang_CompileCommands_dispose(cx_commands); |   clang_CompileCommands_dispose(cx_commands); | ||||||
| @ -339,15 +304,17 @@ int ComputeGuessScore(const std::string& a, const std::string& b) { | |||||||
| 
 | 
 | ||||||
| void Project::Load(const std::vector<std::string>& extra_flags, | void Project::Load(const std::vector<std::string>& extra_flags, | ||||||
|                    const std::string& directory) { |                    const std::string& directory) { | ||||||
|   IncludeDirectories includes; |   // Load data.
 | ||||||
|   entries = |   ProjectConfig config; | ||||||
|       LoadCompilationEntriesFromDirectory(&includes, extra_flags, directory); |   config.extra_flags = extra_flags; | ||||||
| 
 |   config.project_dir = directory; | ||||||
|   quote_include_directories.assign(includes.quote_dirs.begin(), |   entries = LoadCompilationEntriesFromDirectory(&config); | ||||||
|                                    includes.quote_dirs.end()); |  | ||||||
|   angle_include_directories.assign(includes.angle_dirs.begin(), |  | ||||||
|                                    includes.angle_dirs.end()); |  | ||||||
| 
 | 
 | ||||||
|  |   // Cleanup / postprocess include directories.
 | ||||||
|  |   quote_include_directories.assign(config.quote_dirs.begin(), | ||||||
|  |                                    config.quote_dirs.end()); | ||||||
|  |   angle_include_directories.assign(config.angle_dirs.begin(), | ||||||
|  |                                    config.angle_dirs.end()); | ||||||
|   for (std::string& path : quote_include_directories) { |   for (std::string& path : quote_include_directories) { | ||||||
|     EnsureEndsInSlash(path); |     EnsureEndsInSlash(path); | ||||||
|     LOG_S(INFO) << "quote_include_dir: " << path; |     LOG_S(INFO) << "quote_include_dir: " << path; | ||||||
| @ -357,6 +324,7 @@ void Project::Load(const std::vector<std::string>& extra_flags, | |||||||
|     LOG_S(INFO) << "angle_include_dir: " << path; |     LOG_S(INFO) << "angle_include_dir: " << path; | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|  |   // Setup project entries.
 | ||||||
|   absolute_path_to_entry_index_.resize(entries.size()); |   absolute_path_to_entry_index_.resize(entries.size()); | ||||||
|   for (int i = 0; i < entries.size(); ++i) |   for (int i = 0; i < entries.size(); ++i) | ||||||
|     absolute_path_to_entry_index_[entries[i].filename] = i; |     absolute_path_to_entry_index_[entries[i].filename] = i; | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user