27 if (searchString.
ConsumeChar<lang::Case::Sensitive, lang::Whitespaces::Trim>(
'^'))
31 if ( searchString.
Length() > 1 && searchString.
CharAt<
NC>(1) ==
';') {
32 kindSpecChar= searchString.
CharAt<
NC>(0);
35 if (searchString.
ConsumeChar<lang::Case::Sensitive, lang::Whitespaces::Trim>(
'^'))
39 switch (tolower(kindSpecChar)) {
63 if (displayStart>=0) {
139 nextPos= std::min(nextPos, tmpScope[
scopeSize-1].IndexOfOrLength(
'\\'));
140 if (nextPos== tmpScope[
scopeSize-1].Length())
152 scope[i]= tmpScope[i];
160 if (searchString.
CharAt(8) ==
' ' ) {
168 }
else if (searchString.
CharAt(8) ==
'<' ) {
184 auto getNextIdentiferWithTemplateArgs = [&](
Substring& src,
String& word) {
186 int templateDepth= 0;
200 if (src.
ConsumeChar(
'<')) {++templateDepth;
continue;}
203 if (templateDepth > 0 ) {
220 for (;searchString.
TrimStart().IsNotEmpty();) {
222 getNextIdentiferWithTemplateArgs(searchString, word);
253 scope[i]= tmpScope[i];
271 while ( depth > 0 || !searchString.
ConsumeChar(
']') ) {
282 if (templateStart == 8 &&
scope[
scopeSize-1].StartsWith(
"operator") ) {
285 templateStart=
scope[
scopeSize-1].IndexOf(
'<', templateStart + 1);
287 if (templateStart>=0) {
328 bool scopeFound=
true;
343 ,0,
false,
false,
false,
false,
false,
false
359 !targetCursor.IsRoot() ) {
378 int cntLoggers;
Lox_IsActive(cntLoggers, Verbosity::Info,
"DXL/INDIRECT")
379 if (cntLoggers > 0) {
382 parentLog <<
" " << p.Name() <<
NEW_LINE;
383 Lox_Info(
"DXL/INDIRECT",
"Potential parents of XLink {!Q} are\n{}",
398 Lox_Info(
"DXL/INDIRECT",
"Type definition for {} found: {}", origSearchString, typeDef.
Type)
408 if ( (typeDefTargetCursor= index->Root()).AsCursor().GoTo(typeDefPath).IsEmpty() )
411 typeDefTargetCursor= index->Root();
414 if (typeDefTargetCursor.IsRoot()) {
420 while (!scopeParentCursor.IsRoot()) {
421 if((typeDefTargetCursor= scopeParentCursor).AsCursor().GoTo(typeDefPath).IsEmpty() )
423 auto newScopeParentCursor= typeDefTargetCursor.
Parent();
424 typeDefTargetCursor.
AsCursor().GoToRoot();
425 if( newScopeParentCursor == scopeParentCursor )
427 scopeParentCursor= newScopeParentCursor;
431 if (typeDefTargetCursor.IsRoot()) {
432 Lox_Info(
"The type definition {!Q} was not found in the tag file {}:1. "
433 "While processing XLink {!Q}. This is probably an inherited type definition "
434 "to be resolved later",
436 return typeDefTargetCursor;
441 typeDefCursor= typeDefTargetCursor;
446 return typeDefTargetCursor;
455 for (
auto& baseTypeName : bases) {
469 if ( (baseType= index->Root()).AsCursor().GoTo(baseTypePath).IsEmpty() ) {
471 Lox_Error(
"The specified base entity {!Q} is not a record or a type defintion, but a {}. "
472 "Detected in tag-file {!Q}",
473 baseTypePath, baseType.
Kind(), index->FilePath )
485 Lox_Error(
"The specified base entity {!Q} does not exist in any tag-file.", baseTypeName)
493 if ( i>= previousResultSize && i < newResultSize )
507 bool starGiven =
false;
508 bool addFArgs =
false;
509 bool addTArgs =
false;
510 bool addSubscript =
false;
511 bool addType =
false;
512 bool addQualifiers =
false;
517 || display.
ConsumeChar(
'>') ) { addTArgs =
true;
continue; }
519 || display.
ConsumeChar(
')') ) { addFArgs =
true;
continue; }
521 || display.
ConsumeChar(
']') ) { addSubscript =
true;
continue; }
522 if ( display.
ConsumeChar(
'?') ) { addType =
true;
continue; }
523 if ( display.
ConsumeChar(
'!') ) { addQualifiers =
true;
continue; }
524 if ( display.
ConsumeChar(
'*') ) { starGiven =
true;
continue; }
530 addFArgs= addTArgs= addSubscript= addType= addQualifiers=
true;
556 if ( addFArgs | addTArgs | addSubscript | addType | addQualifiers )
569 ||
Result().IsIndirectByInheritance
570 ||
Result().IsResolvedTypeDef );
573 if ( display.
IsNotEmpty() && !addFArgs && !addTArgs && !addType && addParents < 2 ) {
584 rec && rec->TemplateArgs) {
586 newDisplay.
_(
"template ");
587 rec->TemplateArgs->Print(newDisplay);
588 newDisplay.
_<
NC>(
' ');
594 newDisplay << var->Type <<
' ';
596 func && func->Type.IsNotEmpty())
597 newDisplay << func->Type <<
' ';
607 for (
int i= addParents-2 ; i>= 0; --i) {
610 newDisplay <<
Scope(parentIdx);
624 int cntParentOverflow = 0;
625 for (; cntParentOverflow < addParents && !parent.IsRoot(); ++cntParentOverflow)
627 if ( parent.IsRoot() && cntParentOverflow < addParents)
630 n.Parent().Path(newDisplay, parent); }
633 if (prevDisplayLength != newDisplay.
Length()){
637 newDisplay.
_<
NC>(
"::");
641 newDisplay <<
Name();
651 if ( func->Args ) func->Args->Print(newDisplay);
652 else newDisplay.
_(
"()");
657 newDisplay.
_<
NC>(
' ')._<NC>(func->Qualifiers);
659 if (newDisplay.
EndsWith(
"noexcept") )
678 && (addSubscript ||
Subscript.IsNotNull()) )
679 newDisplay << Cast<TGTVariable,NC>(target)->Subscript;
683 newDisplay.
_<
NC>(
" (");
685 int cntParentOverflow = 0;
686 for (; cntParentOverflow < addParents && !parent.IsRoot(); ++cntParentOverflow)
687 parent= parent.Parent();
688 if ( parent.IsRoot() && cntParentOverflow < addParents)
692 newDisplay.
_<
NC>(
") ");
696 newDisplay << display;
701#if defined(TODO_IS_NEEDED_AGAIN)
726 integer scopeStart = fileName.StartsWith(
"struct") ? 6
727 : fileName.StartsWith(
"class") ? 5
728 : fileName.StartsWith(
"union") ? 5
729 : fileName.StartsWith(
"namespace") ? 9
730 : fileName.StartsWith(
"concept") ? 7
734 fileName.ShortenTo( fileName.LastIndexOf(
'.') );
737 fileName.DeleteStart(scopeStart);
738 fileName.SearchAndReplace(
"_8" ,
"@" );
739 fileName.SearchAndReplace(
"_1_1",
"@" );
740 fileName.SearchAndReplace(
"__" ,
"_" );
745 while (parser.IsNotEmpty() && scopeSize < MAX_SCOPE_DEPTH )
746 fileScope[scopeSize++]=
String( ma, parser.ConsumeToken(
'@') );
754 auto htmlFileHandle= htmlFile.
AsCursor().Export();
758 return std::make_pair(xl,
false);
780 return std::make_pair(xl,
true);
786 auto printType= [&](
const String& headLine,
const Index::Node& targetNode,
bool withPath) {
793 rec && rec->TemplateArgs )
796 bool isMember = targetNode.Parent()!=targetNode.Index().Root()
798 bool isConstructor= isMember
801 kindName= !isMember ?
"namespace-function"
802 : isConstructor ?
"constructor"
805 kindName= isMember ?
"member-variable" :
"namespace-variable";
807 rec && rec->SpecializationArgs )
808 kindName=
"specialization";
810 kindName= macro->Args ?
"preprocessor macro"
811 :
"preprocessor constant";
812 else kindName= target->
Kind();
829 if( typeCode) np.
_(
"(").
_(typeCode).
_(
") ");
835 rec && rec->TemplateArgs ) {
837 rec->TemplateArgs->Print(np);
840 if (withPath && !target->
IsA(
Target::Macro) && !targetNode.Parent().IsRoot()) {
843 targetNode.Parent().Path(pathBuf); }
844 np.
_(pathBuf).
_<
NC>(
"::");
847 String name= targetNode.Name();
855 if (
auto* rec=
Cast<TGTRecord>(target); rec && rec->SpecializationArgs )
856 rec->SpecializationArgs->Print(np);
859 np << var->Subscript;
862 macro->Args->Print(np);
864 String256 link(targetNode.Index().BaseURL);
867 link <<
'#' << mem->Anchor;
871 targetNode.Parent().Path(pathBuf);
872 np.
_<
NC>(
" in file: ")._<NC>(pathBuf);
878 out.
Add(
"{} {} {!ATab} {}:{} {!ATab} {} "
882 , targetNode.Index().FilePath
906 && !
Result().IsIndirectByInheritance
907 && !
Result().IsIndirectByTypeDef
908 && !
Result().IsIndirectLinkToScannedHTMLSourceFile ) {
909 out.
Add(
"Warning: XLink #{!Q} uses indirection prefix '^', while it targets a "
910 "direct member in the parent scope.\n"
911 " Hint: Remove the prefix from the XLink", linkString );
912 printType(
" Target:",
Result().Node,
true);
917 && (
Result().IsIndirectByInheritance
918 ||
Result().IsIndirectByTypeDef ) ) {
923 out.
Add(
"Warning: XLink #{!Q} has an indirect target but is not marked with the "
924 "indirection prefix '^'.",
926 printType(
" Target:",
Result().Node,
true);
932 &&
Result().IsIndirectLinkToScannedHTMLSourceFile ) {
933 out.
Add(
"Warning: XLink #{!Q} links to an HTML-file found in the output folder "
934 "(not the tag file)!\n"
935 "Mark this link with indirection prefix '^' (to silence this warning).",
937 printType(
" Target:",
Result().Node,
true);
942 "No error to print for this valid XLink \"{}\" in the sources", linkString )
951 if (target.Node == it)
981 out.
Add(
"Ambiguous XLink #{!Q}.", linkString);
986 printType(
"Could be", target.Node,
true);
994 printType(
"Could be", variable,
true);
998 out.
Add(
"Further entities with the same name:");
1001 printType(
"", node,
true);
1009 out.
Add(
"Unresolved XLink #{!Q}.", linkString);
1020 ALIB_DBG(
MA.DbgCriticalSectionsPH->DCSLock=
nullptr;)
1022 out.
Buffer << (
" Given parent scope \"");
1028 out.
Buffer << (
"\" not found.\n");
1033 out.
Add(
"Collecting proposals of compound type(s) and base types: ");
1037 std::vector<Index::Node> parents;
1043 parents.push_back(target.Node);
1046 parents.push_back(target);
1049 parents.push_back(target);
1051 bool foundSimilar=
false;
1052 for (
int phase=0 ; phase<5 ; ++phase) {
1053 for (
auto& didYouMeanChildOf : parents) {
1061 auto child= didYouMeanChildOf.AsCursor().FirstChild();
1062 while ( child.IsValid() ) {
1065 && ( child.Name().StartsWith<CHK,lang::Case::Sensitive>(searchedName)
1066 || searchedName.
StartsWith<
CHK,lang::Case::Sensitive>(child.Name()) ) )
1068 && ( child.Name().StartsWith<CHK,lang::Case::Ignore >(searchedName)
1069 || searchedName.
StartsWith<
CHK,lang::Case::Ignore >(child.Name()) ) )
1071 && ( child.Name().IndexOf <NC,lang::Case::Sensitive>(searchedName) >=0
1072 || searchedName.
IndexOf <
NC,lang::Case::Sensitive>(child.Name()) >=0 ) )
1074 && ( child.Name().IndexOf <NC,lang::Case::Ignore >(searchedName) >=0
1075 || searchedName.
IndexOf <
NC,lang::Case::Ignore >(child.Name()) >=0 ) )
1079 if (!foundSimilar) {
1080 printType(
"Did you mean an entity in", didYouMeanChildOf,
true);
1083 printType(
" ", child,
false);
1085 child.GoToNextSibling();
1089 else if ( !foundSimilar) {
1090 auto child= didYouMeanChildOf.AsCursor().FirstChild();
1091 while (child.IsValid()) {
1093 if (!foundSimilar) {
1094 printType(
"Did you mean an entity in", didYouMeanChildOf,
true);
1097 printType(
" ", child,
false);
1099 child.GoToNextSibling();
1114 printType(
"Or ", indexCursor,
true);
1124 :
"Did you mean overloaded",
1131 printType(
"Subscript mismatch with: ", indexCursor,
true);
1136 printType(
"Did you mean", indexCursor,
true);
#define ALIB_LOCK_SHARED_WITH(lock)
#define ALIB_ASSERT(cond, domain)
#define ALIB_ASSERT_WARNING(cond, domain,...)
#define Lox_IsActive(result,...)
std::pair< Iterator, bool > InsertIfNotExistent(const KeyType &key, const MappedType &mapped)
TAString & InsertChars(TChar c, integer qty)
integer SearchAndReplace(const TString< TChar > &needle, const TString< TChar > &replacement, integer startIdx=0, integer maxReplacements=strings::MAX_LEN, lang::Case sensitivity=lang::Case::Sensitive, integer endIdx=strings::MAX_LEN)
TAString & ShortenTo(integer newLength)
TAString & ShortenBy(integer charsToRemove)
void DbgDisableBufferReplacementWarning()
constexpr integer Length() const
constexpr bool IsEmpty() const
bool EndsWith(const TString &needle) const
TChar CharAtStart() const
TChar CharAt(integer idx) const
constexpr bool IsNotEmpty() const
integer IndexOf(const TString &needle, integer startIdx=0, integer endIdx=strings::MAX_LEN) const
integer LastIndexOf(TChar needle, integer startIndex=MAX_LEN) const
TString< TChar > Substring(integer regionStart, integer regionLength=MAX_LEN) const
bool Equals(const TString< TChar > &rhs) const
bool StartsWith(const TString &needle) const
integer IndexOfOrLength(TChar needle) const
bool ConsumeString(const TString< TChar > &consumable)
TSubstring & TrimStart(const TCString< TChar > &whiteSpaces=CStringConstantsTraits< TChar >::DefaultWhitespaces())
integer ConsumeChars(integer regionLength, TAString< TChar, TAllocator > &target, integer separatorWidth=0)
TSubstring & Trim(const TCString< TChar > &whiteSpaces=CStringConstantsTraits< TChar >::DefaultWhitespaces())
integer ConsumeCharsFromEnd(integer regionLength, TAString< TChar, TAllocator > &target, integer separatorWidth=0)
TSubstring & TrimEnd(const TCString< TChar > &whiteSpaces=CStringConstantsTraits< TChar >::DefaultWhitespaces())
const alib::String & BaseURL
The URL of the HTML-output created with this tag-file.
alib::PathString FilePath
The path to the doxygenTagFile.
void ReplaceToTreeSeparator(alib::AString &buffer, Target::Kinds kind, alib::integer startPos=0)
Node ImportNode(CursorHandle handle)
Target(Kinds pKind, const alib::String &htmlFile, int lineNo)
bool IsA(Kinds aKind) const
alib::String HTMLFile
The HTML file that this target links to (or into).
@ Struct
Denotes a struct.
@ Function
Denotes a namespace- or member-function.
@ Variable
Denotes a namespace- or member-variable.
@ UNSPECIFIED
Used with the field #"XLink::KindSpec;2".
@ Typedef
Denotes a type definition.
@ File
Denotes a source file.
@ EnumElement
Denotes an enumeration element.
@ Concept
Denotes a C++20 concept.
@ Macro
Denotes a preprocessor definition.
@ Dir
Denotes a source folder.
@ Enumeration
Denotes an enumeration.
@ FILEPATH_COMPONENT
A node of a file path (not a doxygen kind).
@ Namespace
Denotes a namespace.
@ DocAnchor
Denotes a preprocessor definition.
@ RECORD
Mask to identify records types.
int LineNo
The line number in the Doxygen tag-file where this entity is defined.
int scopeHintsSize
The number of strings in the array scope that are only hints.
alib::String LinkString
The original source string.
alib::String & Name() const
Index::Node DidYouMeanTemplateType
alib::filetree::FTree::ConstCursorHandle HTMLFileOfLocalLink
The tree node of the HTML file that created this copy of the originally given local XLink.
Index::SearchResult & Result()
XLink()
Constructor. Parses the given searchString and allocates the fields in the ma.
alib::StdVectorMA< Index::Node > DidYouMeanSameName
A list of target nodes with the same name.
alib::StdVectorMA< Index::Node > DidYouMeanNotATemplate
A list of entries that are not templates, while a template type was searched.
alib::ListMA< Index::Node > * TypeDefinitionTargets
void Parse()
Parses the given searchString and allocates the fields in the MA.
const alib::String & Scope(int n) const
void PrintError(alib::Paragraphs &out, const alib::String &linkString, bool suppressHints=false)
void assembleDisplay()
Inner main method of #"AssembleDisplay()".
Target::FunctionArguments * Args
Function arguments provided with the source XLink.
static constexpr int MAX_SCOPE_DEPTH
The maximum number of scope hints and parents.
const alib::String & Hint(int n) const
Target::TemplateArguments * TemplateArgs
alib::StdVectorMA< Index::SearchResult > Targets
alib::ListMA< Index::Node > * BaseTypes
alib::String Subscript
A variable subscript provided by the source XLink.
XLink * linkToParentScope
@ NoTargetNameGiven
No target identifier was given.
@ InappropriateDisplayTweak
@ LocalLinkWithScopeHints
@ TooManyParentsRequested
static Index::Node ResolveTypeDef(const Index::Node &startCursor, const alib::String &origSearchString)
std::pair< XLink *, bool > GetLocalCopy(const alib::filetree::FTFile &htmlFile)
Index::ConstCursorHandle LocalLinkEntity
alib::integer DisplayOriginalPos
void findInherited(const decltype(TGTRecord::BaseTypes)&bases)
XLink * GetLinkToParent()
Errors Error
Possible errors that occured during parsing the search string given by the user.
alib::MonoAllocator MA
The mono allocator used to create the members of the class.
alib::StdVectorMA< Index::Node > DidYouMeanVariable
A list of entries that are variables, while the XLink's subscript does not match.
Target::Kinds KindSpec
Function arguments provided with the source XLink.
alib::String Qualifiers
Function qualifiers like const, or nothrow provided with the source XLink.
Target::TemplateArguments * SpecializationArgs
alib::StdVectorMA< Index::Node > DidYouMeanFunctionOverload
bool NoIndirectionWarning
monomem::TMonoAllocator< lang::HeapAllocator > MonoAllocator
containers::HashSet< TAllocator, T, THash, TEqual, THashCaching, TRecycling > HashSet
containers::List< T, MonoAllocator, TRecycling > ListMA
LocalString< 64 > String64
constexpr CString NEW_LINE
constexpr const String EMPTY_STRING
monomem::TLocalAllocator< 2 > LocalAllocator2K
strings::TString< character > String
strings::TSubstring< character > Substring
LocalString< 1024 > String1K
LocalString< 128 > String128
LocalString< 256 > String256
constexpr PathCharType DIRECTORY_SEPARATOR
format::Paragraphs Paragraphs
LocalString< 32 > String32
LocalString< 512 > String512
const TGT * Cast(const Index::Node &node)
The cursor type of the #"StringTree".
const alib::String & HTMLFile() const
const Target * Target() const
alib::strings::TAString< cmTree::CharacterType, alib::lang::HeapAllocator > & Path(alib::strings::TAString< cmTree::CharacterType > &targetString, alib::lang::CurrentData targetData=alib::lang::CurrentData::Clear) const
bool IsA(Target::Kinds kind) const
Target::Kinds Kind() const
int FunctionArgumentMatch
Node Node
The cursor pointing to the result.
bool IsIndirectByInheritance
Set if a member was found in a base type and not in the originally given one.
alib::ListMA< alib::String > BaseTypes
The base type of the record.
XLink target information for type definitions.
alib::String Type
The type of the definition.
static FunctionArguments * PARSE(alib::MonoAllocator &ma, alib::Substring &parser)
static TemplateArguments * PARSE(alib::MonoAllocator &ma, alib::Substring &parser)