28 if (searchString.
ConsumeChar<lang::Case::Sensitive, lang::Whitespaces::Trim>(
'^'))
32 if ( searchString.
Length() > 1 && searchString.
CharAt<
NC>(1) ==
';') {
33 kindSpecChar= searchString.
CharAt<
NC>(0);
36 if (searchString.
ConsumeChar<lang::Case::Sensitive, lang::Whitespaces::Trim>(
'^'))
40 switch (tolower(kindSpecChar)) {
64 if (displayStart>=0) {
141 nextPos= std::min(nextPos, tmpScope[
scopeSize-1].IndexOfOrLength(
'\\'));
142 if (nextPos== tmpScope[
scopeSize-1].Length())
155 scope[i]= tmpScope[i];
163 if (searchString.
CharAt(8) ==
' ' ) {
171 }
else if (searchString.
CharAt(8) ==
'<' ) {
188 auto getNextIdentiferWithTemplateArgs = [&](
Substring& src,
String& word) {
190 int templateDepth= 0;
204 if (src.
ConsumeChar(
'<')) {++templateDepth;
continue;}
207 if (templateDepth > 0 ) {
224if(
LinkString.Equals(
"todo .fTreeSources;source-file tree"))
227 for (;searchString.
TrimStart().IsNotEmpty();) {
229 getNextIdentiferWithTemplateArgs(searchString, word);
261 scope[i]= tmpScope[i];
279 while ( depth > 0 || !searchString.
ConsumeChar(
']') ) {
290 if (templateStart == 8 &&
scope[
scopeSize-1].StartsWith(
"operator") ) {
293 templateStart=
scope[
scopeSize-1].IndexOf(
'<', templateStart + 1);
295 if (templateStart>=0) {
336 bool scopeFound=
true;
352 ,
false,
false,
false,
false,
false,
false,
false
368 !targetCursor.IsRoot() ) {
388 int cntLoggers;
Lox_IsActive(cntLoggers, Verbosity::Info,
"DXL/INDIRECT")
389 if (cntLoggers > 0) {
392 parentLog <<
" " << p.Name() <<
NEW_LINE;
393 Lox_Info(
"DXL/INDIRECT",
"Potential parents of XLink {!Q} are\n{}",
409 Lox_Info(
"DXL/INDIRECT",
"Type definition for {} found: {}", origSearchString, typeDef.
Type)
419 if ( (typeDefTargetCursor= index->Root()).AsCursor().GoTo(typeDefPath).IsEmpty() )
422 typeDefTargetCursor= index->Root();
425 if (typeDefTargetCursor.IsRoot()) {
431 while (!scopeParentCursor.IsRoot()) {
432 if((typeDefTargetCursor= scopeParentCursor).AsCursor().GoTo(typeDefPath).IsEmpty() )
434 auto newScopeParentCursor= typeDefTargetCursor.
Parent();
435 typeDefTargetCursor.
AsCursor().GoToRoot();
436 if( newScopeParentCursor == scopeParentCursor )
438 scopeParentCursor= newScopeParentCursor;
442 if (typeDefTargetCursor.IsRoot()) {
443 Lox_Info(
"The type definition {!Q} was not found in the tag file {}:1. "
444 "While processing XLink {!Q}. This is probably an inherited type definition "
445 "to be resolved later",
447 return typeDefTargetCursor;
452 typeDefCursor= typeDefTargetCursor;
457 return typeDefTargetCursor;
466 for (
auto& baseTypeName : bases) {
480 if ( (baseType= index->Root()).AsCursor().GoTo(baseTypePath).IsEmpty() ) {
482 Lox_Error(
"The specified base entity {!Q} is not a record or a type defintion, but a {}. "
483 "Detected in tag-file {!Q}",
484 baseTypePath, baseType.
Kind(), index->FilePath )
497 Lox_Error(
"The specified base entity {!Q} does not exist in any tag-file.", baseTypeName)
506 if ( i>= previousResultSize && i < newResultSize )
520 bool starGiven =
false;
521 bool addFArgs =
false;
522 bool addTArgs =
false;
523 bool addSubscript =
false;
524 bool addType =
false;
525 bool addQualifiers =
false;
530 || display.
ConsumeChar(
'>') ) { addTArgs =
true;
continue; }
532 || display.
ConsumeChar(
')') ) { addFArgs =
true;
continue; }
534 || display.
ConsumeChar(
']') ) { addSubscript =
true;
continue; }
535 if ( display.
ConsumeChar(
'?') ) { addType =
true;
continue; }
536 if ( display.
ConsumeChar(
'!') ) { addQualifiers =
true;
continue; }
537 if ( display.
ConsumeChar(
'*') ) { starGiven =
true;
continue; }
543 addFArgs= addTArgs= addSubscript= addType= addQualifiers=
true;
569 if ( addFArgs | addTArgs | addSubscript | addType | addQualifiers )
583 ||
Result().IsIndirectByInheritance
584 ||
Result().IsResolvedTypeDef );
587 if ( display.
IsNotEmpty() && !addFArgs && !addTArgs && !addType && addParents < 2 ) {
599 rec && rec->TemplateArgs) {
601 newDisplay.
_(
"template ");
602 rec->TemplateArgs->Print(newDisplay);
603 newDisplay.
_<
NC>(
' ');
610 newDisplay << var->Type <<
' ';
612 func && func->Type.IsNotEmpty())
613 newDisplay << func->Type <<
' ';
623 for (
int i= addParents-2 ; i>= 0; --i) {
626 newDisplay <<
Scope(parentIdx);
640 int cntParentOverflow = 0;
641 for (; cntParentOverflow < addParents && !parent.IsRoot(); ++cntParentOverflow)
643 if ( parent.IsRoot() && cntParentOverflow < addParents)
646 n.Parent().Path(newDisplay, parent); }
649 if (prevDisplayLength != newDisplay.
Length()){
653 newDisplay.
_<
NC>(
"::");
658 newDisplay <<
Name();
668 if ( func->Args ) func->Args->Print(newDisplay);
669 else newDisplay.
_(
"()");
674 newDisplay.
_<
NC>(
' ')._<NC>(func->Qualifiers);
676 if (newDisplay.
EndsWith(
"noexcept") )
695 && (addSubscript ||
Subscript.IsNotNull()) )
696 newDisplay << Cast<TGTVariable,NC>(target)->Subscript;
700 newDisplay.
_<
NC>(
" (");
702 int cntParentOverflow = 0;
703 for (; cntParentOverflow < addParents && !parent.IsRoot(); ++cntParentOverflow)
704 parent= parent.Parent();
705 if ( parent.IsRoot() && cntParentOverflow < addParents)
709 newDisplay.
_<
NC>(
") ");
714 newDisplay << display;
720#if defined(TODO_IS_NEEDED_AGAIN)
745 integer scopeStart = fileName.StartsWith(
"struct") ? 6
746 : fileName.StartsWith(
"class") ? 5
747 : fileName.StartsWith(
"union") ? 5
748 : fileName.StartsWith(
"namespace") ? 9
749 : fileName.StartsWith(
"concept") ? 7
753 fileName.ShortenTo( fileName.LastIndexOf(
'.') );
756 fileName.DeleteStart(scopeStart);
757 fileName.SearchAndReplace(
"_8" ,
"@" );
758 fileName.SearchAndReplace(
"_1_1",
"@" );
759 fileName.SearchAndReplace(
"__" ,
"_" );
764 while (parser.IsNotEmpty() && scopeSize < MAX_SCOPE_DEPTH )
765 fileScope[scopeSize++]=
String( ma, parser.ConsumeToken(
'@') );
773 auto htmlFileHandle= htmlFile.
AsCursor().Export();
777 return std::make_pair(xl,
false);
799 return std::make_pair(xl,
true);
805 auto printType= [&](
const String& headLine,
const Index::Node& targetNode,
bool withPath) {
812 rec && rec->TemplateArgs )
815 bool isMember = targetNode.Parent()!=targetNode.Index().Root()
817 bool isConstructor= isMember
820 kindName= !isMember ?
"namespace-function"
821 : isConstructor ?
"constructor"
824 kindName= isMember ?
"member-variable" :
"namespace-variable";
826 rec && rec->SpecializationArgs )
827 kindName=
"specialization";
829 kindName= macro->Args ?
"preprocessor macro"
830 :
"preprocessor constant";
831 else kindName= target->
Kind();
848 if( typeCode) np.
_(
"(").
_(typeCode).
_(
") ");
854 rec && rec->TemplateArgs ) {
856 rec->TemplateArgs->Print(np);
859 if (withPath && !target->
IsA(
Target::Macro) && !targetNode.Parent().IsRoot()) {
862 targetNode.Parent().Path(pathBuf); }
863 np.
_(pathBuf).
_<
NC>(
"::");
866 String name= targetNode.Name();
874 if (
auto* rec=
Cast<TGTRecord>(target); rec && rec->SpecializationArgs )
875 rec->SpecializationArgs->Print(np);
878 np << var->Subscript;
881 macro->Args->Print(np);
883 String256 link(targetNode.Index().BaseURL);
886 link <<
'#' << mem->Anchor;
890 targetNode.Parent().Path(pathBuf);
891 np.
_<
NC>(
" in file: ")._<NC>(pathBuf);
897 out.
Add(
"{} {} {!ATab} {}:{} {!ATab} {} "
901 , targetNode.Index().FilePath
925 && !
Result().IsIndirectByInheritance
926 && !
Result().IsIndirectByTypeDef
927 && !
Result().IsIndirectLinkToScannedHTMLSourceFile ) {
928 out.
Add(
"Warning: XLink #{!Q} uses indirection prefix '^', while it targets a "
929 "direct member in the parent scope.\n"
930 " Hint: Remove the prefix from the XLink", linkString );
931 printType(
" Target:",
Result().Node,
true);
936 && (
Result().IsIndirectByInheritance
937 ||
Result().IsIndirectByTypeDef
938 ||
Result().IsIndirectLinkToScannedHTMLSourceFile ) ) {
939 out.
Add(
"Warning: XLink #{!Q} has an indirect target but is not marked with the "
940 "indirection prefix '^'.",
942 printType(
" Target:",
Result().Node,
true);
947 &&
Result().IsIndirectLinkToScannedHTMLSourceFile ) {
948 out.
Add(
"Warning: XLink #{!Q} links to an HTML-file found in the output folder "
949 "(not the tag file)!\n"
950 "Mark this link with indirection prefix '^' (to silence this warning).",
952 printType(
" Target:",
Result().Node,
true);
957 "No error to print for this valid XLink \"{}\" in the sources", linkString )
966 if (target.Node == it)
996 out.
Add(
"Ambiguous XLink #{!Q}.", linkString);
1001 printType(
"Could be", target.Node,
true);
1009 printType(
"Could be", variable,
true);
1013 out.
Add(
"Further entities with the same name:");
1016 printType(
"", node,
true);
1024 out.
Add(
"Unresolved XLink #{!Q}.", linkString);
1035 ALIB_DBG(
MA.DbgCriticalSectionsPH->DCSLock=
nullptr;)
1037 out.
Buffer << (
" Given parent scope \"");
1043 out.
Buffer << (
"\" not found.\n");
1048 out.
Add(
"Collecting proposals of compound type(s) and base types: ");
1052 std::vector<Index::Node> parents;
1058 parents.push_back(target.Node);
1061 parents.push_back(target);
1064 parents.push_back(target);
1066 bool foundSimilar=
false;
1067 for (
int phase=0 ; phase<5 ; ++phase) {
1068 for (
auto& didYouMeanChildOf : parents) {
1076 auto child= didYouMeanChildOf.AsCursor().FirstChild();
1077 while ( child.IsValid() ) {
1080 && ( child.Name().StartsWith<CHK,lang::Case::Sensitive>(searchedName)
1081 || searchedName.
StartsWith<
CHK,lang::Case::Sensitive>(child.Name()) ) )
1083 && ( child.Name().StartsWith<CHK,lang::Case::Ignore >(searchedName)
1084 || searchedName.
StartsWith<
CHK,lang::Case::Ignore >(child.Name()) ) )
1086 && ( child.Name().IndexOf <NC,lang::Case::Sensitive>(searchedName) >=0
1087 || searchedName.
IndexOf <
NC,lang::Case::Sensitive>(child.Name()) >=0 ) )
1089 && ( child.Name().IndexOf <NC,lang::Case::Ignore >(searchedName) >=0
1090 || searchedName.
IndexOf <
NC,lang::Case::Ignore >(child.Name()) >=0 ) )
1094 if (!foundSimilar) {
1095 printType(
"Did you mean an entity in", didYouMeanChildOf,
true);
1098 printType(
" ", child,
false);
1100 child.GoToNextSibling();
1105 else if ( !foundSimilar) {
1106 auto child= didYouMeanChildOf.AsCursor().FirstChild();
1107 while (child.IsValid()) {
1109 if (!foundSimilar) {
1110 printType(
"Did you mean an entity in", didYouMeanChildOf,
true);
1113 printType(
" ", child,
false);
1115 child.GoToNextSibling();
1132 printType(
"Or ", indexCursor,
true);
1142 :
"Did you mean overloaded",
1149 printType(
"Subscript mismatch with: ", indexCursor,
true);
1154 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())
alib::system::PathString FilePath
The path to the doxygenTagFile.
const alib::String & BaseURL
The URL of the HTML-output created with this tag-file.
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
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)
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
alib::files::FTree::ConstCursorHandle HTMLFileOfLocalLink
The tree node of the HTML file which created this copy of the originally given local XLink.
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)
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
std::pair< XLink *, bool > GetLocalCopy(const alib::files::File &htmlFile)
constexpr PathCharType DIRECTORY_SEPARATOR
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
app::AppCliCamp APPCLI_CAMP
strings::TSubstring< character > Substring
LocalString< 1024 > String1K
LocalString< 128 > String128
LocalString< 256 > String256
format::Paragraphs Paragraphs
LocalString< 32 > String32
LocalString< 512 > String512
const TGT * Cast(const Index::Node &node)
void ConvertASCIItoHTMLEntities(alib::AString &buffer)
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
An entry in the vector of search results generated by the method Search.
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)