mirror of
				https://github.com/MaskRay/ccls.git
				synced 2025-11-04 14:17:07 +00:00 
			
		
		
		
	
							parent
							
								
									7e45983d6d
								
							
						
					
					
						commit
						cfdb6bf422
					
				@ -148,20 +148,18 @@ void EmitSemanticHighlighting(QueryDatabase* db,
 | 
				
			|||||||
        break;
 | 
					        break;
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
      case SymbolKind::Var: {
 | 
					      case SymbolKind::Var: {
 | 
				
			||||||
        QueryVar& var = db->GetVar(sym);
 | 
					        if (const QueryVar::Def* def = db->GetVar(sym).AnyDef()) {
 | 
				
			||||||
        if (!var.def)
 | 
					          kind = def->kind;
 | 
				
			||||||
          continue;  // applies to for loop
 | 
					          storage = def->storage;
 | 
				
			||||||
        kind = var.def->kind;
 | 
					          detailed_name = def->ShortName();
 | 
				
			||||||
        storage = var.def->storage;
 | 
					        }
 | 
				
			||||||
        detailed_name = var.def->ShortName();
 | 
					 | 
				
			||||||
        break;
 | 
					        break;
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
      case SymbolKind::Type: {
 | 
					      case SymbolKind::Type: {
 | 
				
			||||||
        QueryType& type = db->GetType(sym);
 | 
					        if (const QueryType::Def* def = db->GetType(sym).AnyDef()) {
 | 
				
			||||||
        if (!type.def)
 | 
					          kind = def->kind;
 | 
				
			||||||
          continue;  // applies to for loop
 | 
					          detailed_name = def->detailed_name;
 | 
				
			||||||
        kind = type.def->kind;
 | 
					        }
 | 
				
			||||||
        detailed_name = type.def->detailed_name;
 | 
					 | 
				
			||||||
        break;
 | 
					        break;
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
      default:
 | 
					      default:
 | 
				
			||||||
 | 
				
			|||||||
@ -56,17 +56,19 @@ BuildInitial(QueryDatabase* db, WorkingFiles* working_files, QueryTypeId root) {
 | 
				
			|||||||
std::vector<Out_CqueryMemberHierarchy::Entry>
 | 
					std::vector<Out_CqueryMemberHierarchy::Entry>
 | 
				
			||||||
ExpandNode(QueryDatabase* db, WorkingFiles* working_files, QueryTypeId root) {
 | 
					ExpandNode(QueryDatabase* db, WorkingFiles* working_files, QueryTypeId root) {
 | 
				
			||||||
  QueryType& root_type = db->types[root.id];
 | 
					  QueryType& root_type = db->types[root.id];
 | 
				
			||||||
  if (!root_type.def)
 | 
					  const QueryType::Def* def = root_type.AnyDef();
 | 
				
			||||||
 | 
					  if (!def)
 | 
				
			||||||
    return {};
 | 
					    return {};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  std::vector<Out_CqueryMemberHierarchy::Entry> ret;
 | 
					  std::vector<Out_CqueryMemberHierarchy::Entry> ret;
 | 
				
			||||||
  EachWithGen(db->vars, root_type.def->vars, [&](QueryVar& var) {
 | 
					  EachWithGen(db->vars, def->vars, [&](QueryVar& var) {
 | 
				
			||||||
 | 
					    const QueryVar::Def* def1 = var.AnyDef();
 | 
				
			||||||
    Out_CqueryMemberHierarchy::Entry entry;
 | 
					    Out_CqueryMemberHierarchy::Entry entry;
 | 
				
			||||||
    entry.name = var.def->ShortName();
 | 
					    entry.name = def1->ShortName();
 | 
				
			||||||
    entry.type_id = var.def->type ? *var.def->type : QueryTypeId();
 | 
					    entry.type_id = def1->type ? *def1->type : QueryTypeId();
 | 
				
			||||||
    if (var.def->spell) {
 | 
					    if (def->spell) {
 | 
				
			||||||
      optional<lsLocation> loc =
 | 
					      optional<lsLocation> loc =
 | 
				
			||||||
          GetLsLocation(db, working_files, *var.def->spell);
 | 
					          GetLsLocation(db, working_files, *def1->spell);
 | 
				
			||||||
      // TODO invalid location
 | 
					      // TODO invalid location
 | 
				
			||||||
      if (loc)
 | 
					      if (loc)
 | 
				
			||||||
        entry.location = *loc;
 | 
					        entry.location = *loc;
 | 
				
			||||||
@ -96,9 +98,9 @@ struct CqueryMemberHierarchyInitialHandler
 | 
				
			|||||||
        break;
 | 
					        break;
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
      if (sym.kind == SymbolKind::Var) {
 | 
					      if (sym.kind == SymbolKind::Var) {
 | 
				
			||||||
        QueryVar& var = db->GetVar(sym);
 | 
					        const QueryVar::Def* def = db->GetVar(sym).AnyDef();
 | 
				
			||||||
        if (var.def && var.def->type)
 | 
					        if (def && def->type)
 | 
				
			||||||
          out.result = BuildInitial(db, working_files, *var.def->type);
 | 
					          out.result = BuildInitial(db, working_files, *def->type);
 | 
				
			||||||
        break;
 | 
					        break;
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
				
			|||||||
@ -55,7 +55,7 @@ struct CqueryRandomHandler : BaseMessageHandler<Ipc_CqueryRandom> {
 | 
				
			|||||||
        sym2id[syms.back()] = n++;
 | 
					        sym2id[syms.back()] = n++;
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    for (RawId i = 0; i < db->vars.size(); i++)
 | 
					    for (RawId i = 0; i < db->vars.size(); i++)
 | 
				
			||||||
      if (db->vars[i].def) {
 | 
					      if (db->vars[i].AnyDef()) {
 | 
				
			||||||
        syms.push_back(SymbolIdx{Id<void>(i), SymbolKind::Var});
 | 
					        syms.push_back(SymbolIdx{Id<void>(i), SymbolKind::Var});
 | 
				
			||||||
        sym2id[syms.back()] = n++;
 | 
					        sym2id[syms.back()] = n++;
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
@ -70,14 +70,14 @@ struct CqueryRandomHandler : BaseMessageHandler<Ipc_CqueryRandom> {
 | 
				
			|||||||
    };
 | 
					    };
 | 
				
			||||||
    n = 0;
 | 
					    n = 0;
 | 
				
			||||||
    for (QueryFunc& func : db->funcs)
 | 
					    for (QueryFunc& func : db->funcs)
 | 
				
			||||||
      if (func.def) {
 | 
					      if (func.AnyDef()) {
 | 
				
			||||||
        add(func.declarations, kDeclWeight);
 | 
					        add(func.declarations, kDeclWeight);
 | 
				
			||||||
        add(func.uses, 1);
 | 
					        add(func.uses, 1);
 | 
				
			||||||
        Add(sym2id, adj, func.derived, n);
 | 
					        Add(sym2id, adj, func.derived, n);
 | 
				
			||||||
        n++;
 | 
					        n++;
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    for (QueryType& type : db->types)
 | 
					    for (QueryType& type : db->types)
 | 
				
			||||||
      if (type.def) {
 | 
					      if (type.AnyDef()) {
 | 
				
			||||||
        add(type.uses, 1);
 | 
					        add(type.uses, 1);
 | 
				
			||||||
        Add(sym2id, adj, type.instances, n);
 | 
					        Add(sym2id, adj, type.instances, n);
 | 
				
			||||||
        Add(sym2id, adj, type.def->funcs, n);
 | 
					        Add(sym2id, adj, type.def->funcs, n);
 | 
				
			||||||
@ -86,7 +86,7 @@ struct CqueryRandomHandler : BaseMessageHandler<Ipc_CqueryRandom> {
 | 
				
			|||||||
        n++;
 | 
					        n++;
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    for (QueryVar& var : db->vars)
 | 
					    for (QueryVar& var : db->vars)
 | 
				
			||||||
      if (var.def) {
 | 
					      if (var.AnyDef()) {
 | 
				
			||||||
        add(var.declarations, kDeclWeight);
 | 
					        add(var.declarations, kDeclWeight);
 | 
				
			||||||
        add(var.uses, 1);
 | 
					        add(var.uses, 1);
 | 
				
			||||||
        n++;
 | 
					        n++;
 | 
				
			||||||
 | 
				
			|||||||
@ -30,10 +30,10 @@ struct CqueryVarsHandler : BaseMessageHandler<Ipc_CqueryVars> {
 | 
				
			|||||||
        default:
 | 
					        default:
 | 
				
			||||||
          break;
 | 
					          break;
 | 
				
			||||||
        case SymbolKind::Var: {
 | 
					        case SymbolKind::Var: {
 | 
				
			||||||
          QueryVar& var = db->GetVar(sym);
 | 
					          const QueryVar::Def* def = db->GetVar(sym).AnyDef();
 | 
				
			||||||
          if (!var.def || !var.def->type)
 | 
					          if (!def || !def->type)
 | 
				
			||||||
            continue;
 | 
					            continue;
 | 
				
			||||||
          id = *var.def->type;
 | 
					          id = *def->type;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        // fallthrough
 | 
					        // fallthrough
 | 
				
			||||||
        case SymbolKind::Type: {
 | 
					        case SymbolKind::Type: {
 | 
				
			||||||
 | 
				
			|||||||
@ -80,11 +80,11 @@ optional<QueryFileId> GetImplementationFile(QueryDatabase* db,
 | 
				
			|||||||
        break;
 | 
					        break;
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
      case SymbolKind::Var: {
 | 
					      case SymbolKind::Var: {
 | 
				
			||||||
        QueryVar& var = db->GetVar(sym);
 | 
					        const QueryVar::Def* def = db->GetVar(sym).AnyDef();
 | 
				
			||||||
        // Note: we ignore the definition if it is in the same file (ie,
 | 
					        // Note: we ignore the definition if it is in the same file (ie,
 | 
				
			||||||
        // possibly a header).
 | 
					        // possibly a header).
 | 
				
			||||||
        if (var.def && var.def->extent) {
 | 
					        if (def && def->extent) {
 | 
				
			||||||
          QueryFileId t = var.def->extent->file;
 | 
					          QueryFileId t = def->extent->file;
 | 
				
			||||||
          if (t != file_id)
 | 
					          if (t != file_id)
 | 
				
			||||||
            return t;
 | 
					            return t;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
				
			|||||||
@ -247,16 +247,14 @@ struct TextDocumentCodeLensHandler
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
        case SymbolKind::Var: {
 | 
					        case SymbolKind::Var: {
 | 
				
			||||||
          QueryVar& var = db->GetVar(sym);
 | 
					          QueryVar& var = db->GetVar(sym);
 | 
				
			||||||
          if (!var.def)
 | 
					          const QueryVar::Def* def = var.AnyDef();
 | 
				
			||||||
            continue;
 | 
					          if (!def || (def->is_local() && !config->codeLensOnLocalVariables))
 | 
				
			||||||
 | 
					 | 
				
			||||||
          if (var.def->is_local() && !config->codeLensOnLocalVariables)
 | 
					 | 
				
			||||||
            continue;
 | 
					            continue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
          bool force_display = true;
 | 
					          bool force_display = true;
 | 
				
			||||||
          // Do not show 0 refs on macro with no uses, as it is most likely
 | 
					          // Do not show 0 refs on macro with no uses, as it is most likely
 | 
				
			||||||
          // a header guard.
 | 
					          // a header guard.
 | 
				
			||||||
          if (var.def->is_macro())
 | 
					          if (def->is_macro())
 | 
				
			||||||
            force_display = false;
 | 
					            force_display = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
          AddCodeLens("ref", "refs", &common, OffsetStartColumn(sym, 0),
 | 
					          AddCodeLens("ref", "refs", &common, OffsetStartColumn(sym, 0),
 | 
				
			||||||
 | 
				
			|||||||
@ -37,10 +37,10 @@ std::vector<Use> GetGotoDefinitionTargets(QueryDatabase* db,
 | 
				
			|||||||
    case SymbolKind::Var: {
 | 
					    case SymbolKind::Var: {
 | 
				
			||||||
      std::vector<Use> ret =
 | 
					      std::vector<Use> ret =
 | 
				
			||||||
          GetDeclarationsOfSymbolForGotoDefinition(db, sym);
 | 
					          GetDeclarationsOfSymbolForGotoDefinition(db, sym);
 | 
				
			||||||
      QueryVar& var = db->GetVar(sym);
 | 
					      QueryVar::Def* def = db->GetVar(sym).AnyDef();
 | 
				
			||||||
      if (var.def && var.def->type) {
 | 
					      if (def && def->type) {
 | 
				
			||||||
        std::vector<Use> types = GetDeclarationsOfSymbolForGotoDefinition(
 | 
					        std::vector<Use> types = GetDeclarationsOfSymbolForGotoDefinition(
 | 
				
			||||||
            db, SymbolIdx{*var.def->type, SymbolKind::Type});
 | 
					            db, SymbolIdx{*def->type, SymbolKind::Type});
 | 
				
			||||||
        ret.insert(ret.end(), types.begin(), types.end());
 | 
					        ret.insert(ret.end(), types.begin(), types.end());
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
      return ret;
 | 
					      return ret;
 | 
				
			||||||
 | 
				
			|||||||
@ -9,30 +9,27 @@ std::pair<std::string_view, std::string_view> GetCommentsAndHover(
 | 
				
			|||||||
    SymbolRef sym) {
 | 
					    SymbolRef sym) {
 | 
				
			||||||
  switch (sym.kind) {
 | 
					  switch (sym.kind) {
 | 
				
			||||||
    case SymbolKind::Type: {
 | 
					    case SymbolKind::Type: {
 | 
				
			||||||
      QueryType& type = db->GetType(sym);
 | 
					      if (const auto* def = db->GetType(sym).AnyDef()) {
 | 
				
			||||||
      if (type.def)
 | 
					        return {def->comments, !def->hover.empty()
 | 
				
			||||||
        return {type.def->comments,
 | 
					                                   ? std::string_view(def->hover)
 | 
				
			||||||
                !type.def->hover.empty()
 | 
					                                   : std::string_view(def->detailed_name)};
 | 
				
			||||||
                    ? std::string_view(type.def->hover)
 | 
					      }
 | 
				
			||||||
                    : std::string_view(type.def->detailed_name)};
 | 
					 | 
				
			||||||
      break;
 | 
					      break;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    case SymbolKind::Func: {
 | 
					    case SymbolKind::Func: {
 | 
				
			||||||
      QueryFunc& func = db->GetFunc(sym);
 | 
					      if (const auto* def = db->GetFunc(sym).AnyDef()) {
 | 
				
			||||||
      if (func.def)
 | 
					        return {def->comments, !def->hover.empty()
 | 
				
			||||||
        return {func.def->comments,
 | 
					                                   ? std::string_view(def->hover)
 | 
				
			||||||
                !func.def->hover.empty()
 | 
					                                   : std::string_view(def->detailed_name)};
 | 
				
			||||||
                    ? std::string_view(func.def->hover)
 | 
					      }
 | 
				
			||||||
                    : std::string_view(func.def->detailed_name)};
 | 
					 | 
				
			||||||
      break;
 | 
					      break;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    case SymbolKind::Var: {
 | 
					    case SymbolKind::Var: {
 | 
				
			||||||
      QueryVar& var = db->GetVar(sym);
 | 
					      if (const auto* def = db->GetVar(sym).AnyDef()) {
 | 
				
			||||||
      if (var.def)
 | 
					        return {def->comments, !def->hover.empty()
 | 
				
			||||||
        return {var.def->comments,
 | 
					                                   ? std::string_view(def->hover)
 | 
				
			||||||
                !var.def->hover.empty()
 | 
					                                   : std::string_view(def->detailed_name)};
 | 
				
			||||||
                    ? std::string_view(var.def->hover)
 | 
					      }
 | 
				
			||||||
                    : std::string_view(var.def->detailed_name)};
 | 
					 | 
				
			||||||
      break;
 | 
					      break;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    case SymbolKind::File:
 | 
					    case SymbolKind::File:
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										33
									
								
								src/query.cc
									
									
									
									
									
								
							
							
						
						
									
										33
									
								
								src/query.cc
									
									
									
									
									
								
							@ -772,8 +772,7 @@ void QueryDatabase::RemoveUsrs(SymbolKind usr_kind,
 | 
				
			|||||||
        QueryVar& var = vars[usr_to_var[usr].id];
 | 
					        QueryVar& var = vars[usr_to_var[usr].id];
 | 
				
			||||||
        if (var.symbol_idx)
 | 
					        if (var.symbol_idx)
 | 
				
			||||||
          symbols[var.symbol_idx->id].kind = SymbolKind::Invalid;
 | 
					          symbols[var.symbol_idx->id].kind = SymbolKind::Invalid;
 | 
				
			||||||
        //var.def = QueryVar::Def();
 | 
					        var.def.clear();
 | 
				
			||||||
        var.def = nullopt;
 | 
					 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
      break;
 | 
					      break;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@ -895,10 +894,10 @@ void QueryDatabase::ImportOrUpdate(std::vector<QueryVar::DefUpdate>&& updates) {
 | 
				
			|||||||
    QueryVar& existing = vars[it->second.id];
 | 
					    QueryVar& existing = vars[it->second.id];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Keep the existing definition if it is higher quality.
 | 
					    // Keep the existing definition if it is higher quality.
 | 
				
			||||||
    if (!(existing.def && existing.def->spell &&
 | 
					    if (!(existing.AnyDef() && existing.AnyDef()->spell &&
 | 
				
			||||||
          !def.value.spell)) {
 | 
					          !def.value.spell)) {
 | 
				
			||||||
      existing.def = std::move(def.value);
 | 
					      existing.def.push_front(std::move(def.value));
 | 
				
			||||||
      if (!def.value.is_local())
 | 
					      if (!existing.def.front().is_local())
 | 
				
			||||||
        UpdateSymbols(&existing.symbol_idx, SymbolKind::Var, it->second);
 | 
					        UpdateSymbols(&existing.symbol_idx, SymbolKind::Var, it->second);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
@ -924,19 +923,19 @@ std::string_view QueryDatabase::GetSymbolDetailedName(RawId symbol_idx) const {
 | 
				
			|||||||
        return files[idx].def->path;
 | 
					        return files[idx].def->path;
 | 
				
			||||||
      break;
 | 
					      break;
 | 
				
			||||||
    case SymbolKind::Func:
 | 
					    case SymbolKind::Func:
 | 
				
			||||||
      if (funcs[idx].def) {
 | 
					      if (const auto* def = funcs[idx].AnyDef()) {
 | 
				
			||||||
        auto& def = funcs[idx].def;
 | 
					        // Assume the part after short_name is not needed.
 | 
				
			||||||
        return std::string_view(def->detailed_name)
 | 
					        return std::string_view(def->detailed_name)
 | 
				
			||||||
            .substr(0, def->short_name_offset + def->short_name_size);
 | 
					            .substr(0, def->short_name_offset + def->short_name_size);
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
      break;
 | 
					      break;
 | 
				
			||||||
    case SymbolKind::Type:
 | 
					    case SymbolKind::Type:
 | 
				
			||||||
      if (types[idx].def)
 | 
					      if (const auto* def = types[idx].AnyDef())
 | 
				
			||||||
        return types[idx].def->detailed_name;
 | 
					        return def->detailed_name;
 | 
				
			||||||
      break;
 | 
					      break;
 | 
				
			||||||
    case SymbolKind::Var:
 | 
					    case SymbolKind::Var:
 | 
				
			||||||
      if (vars[idx].def)
 | 
					      if (const auto* def = vars[idx].AnyDef())
 | 
				
			||||||
        return vars[idx].def->detailed_name;
 | 
					        return def->detailed_name;
 | 
				
			||||||
      break;
 | 
					      break;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  return "";
 | 
					  return "";
 | 
				
			||||||
@ -952,16 +951,16 @@ std::string_view QueryDatabase::GetSymbolShortName(RawId symbol_idx) const {
 | 
				
			|||||||
        return files[idx].def->path;
 | 
					        return files[idx].def->path;
 | 
				
			||||||
      break;
 | 
					      break;
 | 
				
			||||||
    case SymbolKind::Func:
 | 
					    case SymbolKind::Func:
 | 
				
			||||||
      if (funcs[idx].def)
 | 
					      if (const auto* def = funcs[idx].AnyDef())
 | 
				
			||||||
        return funcs[idx].def->ShortName();
 | 
					        return def->ShortName();
 | 
				
			||||||
      break;
 | 
					      break;
 | 
				
			||||||
    case SymbolKind::Type:
 | 
					    case SymbolKind::Type:
 | 
				
			||||||
      if (types[idx].def)
 | 
					      if (const auto* def = types[idx].AnyDef())
 | 
				
			||||||
        return types[idx].def->ShortName();
 | 
					        return def->ShortName();
 | 
				
			||||||
      break;
 | 
					      break;
 | 
				
			||||||
    case SymbolKind::Var:
 | 
					    case SymbolKind::Var:
 | 
				
			||||||
      if (vars[idx].def)
 | 
					      if (const auto* def = vars[idx].AnyDef())
 | 
				
			||||||
        return vars[idx].def->ShortName();
 | 
					        return def->ShortName();
 | 
				
			||||||
      break;
 | 
					      break;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  return "";
 | 
					  return "";
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										33
									
								
								src/query.h
									
									
									
									
									
								
							
							
						
						
									
										33
									
								
								src/query.h
									
									
									
									
									
								
							@ -5,6 +5,7 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#include <sparsepp/spp.h>
 | 
					#include <sparsepp/spp.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <forward_list>
 | 
				
			||||||
#include <functional>
 | 
					#include <functional>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct QueryFile;
 | 
					struct QueryFile;
 | 
				
			||||||
@ -145,6 +146,8 @@ struct QueryType {
 | 
				
			|||||||
  std::vector<Use> uses;
 | 
					  std::vector<Use> uses;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  explicit QueryType(const Usr& usr) : usr(usr) {}
 | 
					  explicit QueryType(const Usr& usr) : usr(usr) {}
 | 
				
			||||||
 | 
					  const Def* AnyDef() const { return def ? &*def : nullptr; }
 | 
				
			||||||
 | 
					  Def* AnyDef() { return def ? &*def : nullptr; }
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct QueryFunc {
 | 
					struct QueryFunc {
 | 
				
			||||||
@ -162,6 +165,8 @@ struct QueryFunc {
 | 
				
			|||||||
  std::vector<Use> uses;
 | 
					  std::vector<Use> uses;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  explicit QueryFunc(const Usr& usr) : usr(usr) {}
 | 
					  explicit QueryFunc(const Usr& usr) : usr(usr) {}
 | 
				
			||||||
 | 
					  const Def* AnyDef() const { return def ? &*def : nullptr; }
 | 
				
			||||||
 | 
					  Def* AnyDef() { return def ? &*def : nullptr; }
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct QueryVar {
 | 
					struct QueryVar {
 | 
				
			||||||
@ -172,11 +177,19 @@ struct QueryVar {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  Usr usr;
 | 
					  Usr usr;
 | 
				
			||||||
  Maybe<Id<void>> symbol_idx;
 | 
					  Maybe<Id<void>> symbol_idx;
 | 
				
			||||||
  optional<Def> def;
 | 
					  std::forward_list<Def> def;
 | 
				
			||||||
  std::vector<Use> declarations;
 | 
					  std::vector<Use> declarations;
 | 
				
			||||||
  std::vector<Use> uses;
 | 
					  std::vector<Use> uses;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  explicit QueryVar(const Usr& usr) : usr(usr) {}
 | 
					  explicit QueryVar(const Usr& usr) : usr(usr) {}
 | 
				
			||||||
 | 
					  const Def* AnyDef() const {
 | 
				
			||||||
 | 
					    if (def.empty()) return nullptr;
 | 
				
			||||||
 | 
					    return &def.front();
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  Def* AnyDef() {
 | 
				
			||||||
 | 
					    if (def.empty()) return nullptr;
 | 
				
			||||||
 | 
					    return &def.front();
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct IndexUpdate {
 | 
					struct IndexUpdate {
 | 
				
			||||||
@ -297,21 +310,21 @@ struct QueryDatabase {
 | 
				
			|||||||
      case SymbolKind::File:
 | 
					      case SymbolKind::File:
 | 
				
			||||||
        return QueryFileId(ref.id);
 | 
					        return QueryFileId(ref.id);
 | 
				
			||||||
      case SymbolKind::Func: {
 | 
					      case SymbolKind::Func: {
 | 
				
			||||||
        QueryFunc& file = funcs[ref.id.id];
 | 
					        const QueryFunc::Def* def = funcs[ref.id.id].AnyDef();
 | 
				
			||||||
        if (file.def)
 | 
					        if (def)
 | 
				
			||||||
          return file.def->file;
 | 
					          return def->file;
 | 
				
			||||||
        break;
 | 
					        break;
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
      case SymbolKind::Type: {
 | 
					      case SymbolKind::Type: {
 | 
				
			||||||
        QueryType& type = types[ref.id.id];
 | 
					        const QueryType::Def* def = types[ref.id.id].AnyDef();
 | 
				
			||||||
        if (type.def)
 | 
					        if (def)
 | 
				
			||||||
          return type.def->file;
 | 
					          return def->file;
 | 
				
			||||||
        break;
 | 
					        break;
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
      case SymbolKind::Var: {
 | 
					      case SymbolKind::Var: {
 | 
				
			||||||
        QueryVar& var = vars[ref.id.id];
 | 
					        const QueryVar::Def* def = vars[ref.id.id].AnyDef();
 | 
				
			||||||
        if (var.def)
 | 
					        if (def)
 | 
				
			||||||
          return var.def->file;
 | 
					          return def->file;
 | 
				
			||||||
        break;
 | 
					        break;
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
				
			|||||||
@ -34,9 +34,9 @@ Maybe<Use> GetDefinitionSpellingOfSymbol(QueryDatabase* db,
 | 
				
			|||||||
      break;
 | 
					      break;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    case SymbolKind::Var: {
 | 
					    case SymbolKind::Var: {
 | 
				
			||||||
      QueryVar& var = db->GetVar(sym);
 | 
					      const QueryVar::Def* def = db->GetVar(sym).AnyDef();
 | 
				
			||||||
      if (var.def)
 | 
					      if (def)
 | 
				
			||||||
        return var.def->spell;
 | 
					        return def->spell;
 | 
				
			||||||
      break;
 | 
					      break;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    case SymbolKind::File:
 | 
					    case SymbolKind::File:
 | 
				
			||||||
@ -63,9 +63,9 @@ Maybe<Use> GetDefinitionExtentOfSymbol(QueryDatabase* db, SymbolIdx sym) {
 | 
				
			|||||||
      break;
 | 
					      break;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    case SymbolKind::Var: {
 | 
					    case SymbolKind::Var: {
 | 
				
			||||||
      QueryVar& var = db->GetVar(sym);
 | 
					      const QueryVar::Def* def = db->GetVar(sym).AnyDef();
 | 
				
			||||||
      if (var.def)
 | 
					      if (def)
 | 
				
			||||||
        return var.def->extent;
 | 
					        return def->extent;
 | 
				
			||||||
      break;
 | 
					      break;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    case SymbolKind::File:
 | 
					    case SymbolKind::File:
 | 
				
			||||||
@ -97,9 +97,9 @@ Maybe<QueryFileId> GetDeclarationFileForSymbol(QueryDatabase* db,
 | 
				
			|||||||
      break;
 | 
					      break;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    case SymbolKind::Var: {
 | 
					    case SymbolKind::Var: {
 | 
				
			||||||
      QueryVar& var = db->GetVar(sym);
 | 
					      const QueryVar::Def* def = db->GetVar(sym).AnyDef();
 | 
				
			||||||
      if (var.def)
 | 
					      if (def)
 | 
				
			||||||
        return var.def->file;
 | 
					        return def->file;
 | 
				
			||||||
      break;
 | 
					      break;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    case SymbolKind::File:
 | 
					    case SymbolKind::File:
 | 
				
			||||||
@ -143,8 +143,9 @@ std::vector<Use> ToUses(QueryDatabase* db, const std::vector<QueryVarId>& ids) {
 | 
				
			|||||||
  ret.reserve(ids.size());
 | 
					  ret.reserve(ids.size());
 | 
				
			||||||
  for (auto id : ids) {
 | 
					  for (auto id : ids) {
 | 
				
			||||||
    QueryVar& var = db->vars[id.id];
 | 
					    QueryVar& var = db->vars[id.id];
 | 
				
			||||||
    if (var.def && var.def->spell)
 | 
					    QueryVar::Def* def = var.AnyDef();
 | 
				
			||||||
      ret.push_back(*var.def->spell);
 | 
					    if (def && def->spell)
 | 
				
			||||||
 | 
					      ret.push_back(*def->spell);
 | 
				
			||||||
    else if (var.declarations.size())
 | 
					    else if (var.declarations.size())
 | 
				
			||||||
      ret.push_back(var.declarations[0]);
 | 
					      ret.push_back(var.declarations[0]);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
@ -158,16 +159,20 @@ std::vector<Use> GetUsesOfSymbol(QueryDatabase* db,
 | 
				
			|||||||
    case SymbolKind::Type: {
 | 
					    case SymbolKind::Type: {
 | 
				
			||||||
      QueryType& type = db->GetType(sym);
 | 
					      QueryType& type = db->GetType(sym);
 | 
				
			||||||
      std::vector<Use> ret = type.uses;
 | 
					      std::vector<Use> ret = type.uses;
 | 
				
			||||||
      if (include_decl && type.def && type.def->spell)
 | 
					      if (include_decl) {
 | 
				
			||||||
        ret.push_back(*type.def->spell);
 | 
					        const QueryType::Def* def = type.AnyDef();
 | 
				
			||||||
 | 
					        if (def && def->spell)
 | 
				
			||||||
 | 
					          ret.push_back(*def->spell);
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
      return ret;
 | 
					      return ret;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    case SymbolKind::Func: {
 | 
					    case SymbolKind::Func: {
 | 
				
			||||||
      QueryFunc& func = db->GetFunc(sym);
 | 
					      QueryFunc& func = db->GetFunc(sym);
 | 
				
			||||||
      std::vector<Use> ret = func.uses;
 | 
					      std::vector<Use> ret = func.uses;
 | 
				
			||||||
      if (include_decl) {
 | 
					      if (include_decl) {
 | 
				
			||||||
        if (func.def && func.def->spell)
 | 
					        const QueryFunc::Def* def = func.AnyDef();
 | 
				
			||||||
          ret.push_back(*func.def->spell);
 | 
					        if (def && def->spell)
 | 
				
			||||||
 | 
					          ret.push_back(*def->spell);
 | 
				
			||||||
        AddRange(&ret, func.declarations);
 | 
					        AddRange(&ret, func.declarations);
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
      return ret;
 | 
					      return ret;
 | 
				
			||||||
@ -176,8 +181,9 @@ std::vector<Use> GetUsesOfSymbol(QueryDatabase* db,
 | 
				
			|||||||
      QueryVar& var = db->GetVar(sym);
 | 
					      QueryVar& var = db->GetVar(sym);
 | 
				
			||||||
      std::vector<Use> ret = var.uses;
 | 
					      std::vector<Use> ret = var.uses;
 | 
				
			||||||
      if (include_decl) {
 | 
					      if (include_decl) {
 | 
				
			||||||
        if (var.def && var.def->spell)
 | 
					        const QueryVar::Def* def = var.AnyDef();
 | 
				
			||||||
          ret.push_back(*var.def->spell);
 | 
					        if (def && def->spell)
 | 
				
			||||||
 | 
					          ret.push_back(*def->spell);
 | 
				
			||||||
        ret.insert(ret.end(), var.declarations.begin(), var.declarations.end());
 | 
					        ret.insert(ret.end(), var.declarations.begin(), var.declarations.end());
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
      return ret;
 | 
					      return ret;
 | 
				
			||||||
@ -393,21 +399,21 @@ optional<lsLocationEx> GetLsLocationEx(QueryDatabase* db,
 | 
				
			|||||||
    default:
 | 
					    default:
 | 
				
			||||||
      break;
 | 
					      break;
 | 
				
			||||||
    case SymbolKind::Func: {
 | 
					    case SymbolKind::Func: {
 | 
				
			||||||
      QueryFunc& func = db->GetFunc(use);
 | 
					      const QueryFunc::Def* def = db->GetFunc(use).AnyDef();
 | 
				
			||||||
      if (func.def)
 | 
					      if (def)
 | 
				
			||||||
        ret.containerName = std::string_view(func.def->detailed_name);
 | 
					        ret.containerName = std::string_view(def->detailed_name);
 | 
				
			||||||
      break;
 | 
					      break;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    case SymbolKind::Type: {
 | 
					    case SymbolKind::Type: {
 | 
				
			||||||
      QueryType& type = db->GetType(use);
 | 
					      const QueryType::Def* def = db->GetType(use).AnyDef();
 | 
				
			||||||
      if (type.def)
 | 
					      if (def)
 | 
				
			||||||
        ret.containerName = std::string_view(type.def->detailed_name);
 | 
					        ret.containerName = std::string_view(def->detailed_name);
 | 
				
			||||||
      break;
 | 
					      break;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    case SymbolKind::Var: {
 | 
					    case SymbolKind::Var: {
 | 
				
			||||||
      QueryVar& var = db->GetVar(use);
 | 
					      const QueryVar::Def* def = db->GetVar(use).AnyDef();
 | 
				
			||||||
      if (var.def)
 | 
					      if (def)
 | 
				
			||||||
        ret.containerName = std::string_view(var.def->detailed_name);
 | 
					        ret.containerName = std::string_view(def->detailed_name);
 | 
				
			||||||
      break;
 | 
					      break;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@ -492,17 +498,17 @@ optional<lsSymbolInformation> GetSymbolInfo(QueryDatabase* db,
 | 
				
			|||||||
      return info;
 | 
					      return info;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    case SymbolKind::Var: {
 | 
					    case SymbolKind::Var: {
 | 
				
			||||||
      QueryVar& var = db->GetVar(sym);
 | 
					      const QueryVar::Def* def = db->GetVar(sym).AnyDef();
 | 
				
			||||||
      if (!var.def)
 | 
					      if (!def)
 | 
				
			||||||
        break;
 | 
					        break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      lsSymbolInformation info;
 | 
					      lsSymbolInformation info;
 | 
				
			||||||
      if (use_short_name)
 | 
					      if (use_short_name)
 | 
				
			||||||
        info.name = var.def->ShortName();
 | 
					        info.name = def->ShortName();
 | 
				
			||||||
      else
 | 
					      else
 | 
				
			||||||
        info.name = var.def->detailed_name;
 | 
					        info.name = def->detailed_name;
 | 
				
			||||||
      info.containerName = var.def->detailed_name;
 | 
					      info.containerName = def->detailed_name;
 | 
				
			||||||
      switch (var.def->kind) {
 | 
					      switch (def->kind) {
 | 
				
			||||||
        default:
 | 
					        default:
 | 
				
			||||||
          info.kind = lsSymbolKind::Variable;
 | 
					          info.kind = lsSymbolKind::Variable;
 | 
				
			||||||
          break;
 | 
					          break;
 | 
				
			||||||
 | 
				
			|||||||
@ -69,15 +69,15 @@ void EachWithGen(std::vector<Q>& collection, Id<Q> x, Fn fn) {
 | 
				
			|||||||
  Q& obj = collection[x.id];
 | 
					  Q& obj = collection[x.id];
 | 
				
			||||||
  // FIXME Deprecate optional<Def> def
 | 
					  // FIXME Deprecate optional<Def> def
 | 
				
			||||||
  //  if (obj.gen == x.gen && obj.def)
 | 
					  //  if (obj.gen == x.gen && obj.def)
 | 
				
			||||||
  if (obj.def)
 | 
					  if (obj.AnyDef())
 | 
				
			||||||
    fn(obj);
 | 
					    fn(obj);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
template <typename Q, typename Fn>
 | 
					template <typename Q, typename Fn>
 | 
				
			||||||
void EachWithGen(std::vector<Q>& collection, std::vector<Id<Q>>& ids, Fn fn) {
 | 
					void EachWithGen(std::vector<Q>& collection, const std::vector<Id<Q>>& ids, Fn fn) {
 | 
				
			||||||
  for (Id<Q> x : ids) {
 | 
					  for (Id<Q> x : ids) {
 | 
				
			||||||
    Q& obj = collection[x.id];
 | 
					    Q& obj = collection[x.id];
 | 
				
			||||||
    if (obj.def) // FIXME Deprecate optional<Def> def
 | 
					    if (obj.AnyDef())
 | 
				
			||||||
      fn(obj);
 | 
					      fn(obj);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user