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 ) {
225 for (;searchString.
TrimStart().IsNotEmpty();) {
227 getNextIdentiferWithTemplateArgs(searchString, word);
259 scope[i]= tmpScope[i];
277 while ( depth > 0 || !searchString.
ConsumeChar(
']') ) {
288 if (templateStart == 8 &&
scope[
scopeSize-1].StartsWith(
"operator") ) {
291 templateStart=
scope[
scopeSize-1].IndexOf(
'<', templateStart + 1);
293 if (templateStart>=0) {
334 bool scopeFound=
true;
350 ,
false,
false,
false,
false,
false,
false,
false
366 !targetCursor.IsRoot() ) {
386 int cntLoggers;
Lox_IsActive(cntLoggers, Verbosity::Info,
"DXL/INDIRECT")
387 if (cntLoggers > 0) {
390 parentLog <<
" " << p.Name() <<
NEW_LINE;
391 Lox_Info(
"DXL/INDIRECT",
"Potential parents of XLink {!Q} are\n{}",
407 Lox_Info(
"DXL/INDIRECT",
"Type definition for {} found: {}", origSearchString, typeDef.
Type)
417 if ( (typeDefTargetCursor= index->Root()).AsCursor().GoTo(typeDefPath).IsEmpty() )
420 typeDefTargetCursor= index->Root();
423 if (typeDefTargetCursor.IsRoot()) {
429 while (!scopeParentCursor.IsRoot()) {
430 if((typeDefTargetCursor= scopeParentCursor).AsCursor().GoTo(typeDefPath).IsEmpty() )
432 auto newScopeParentCursor= typeDefTargetCursor.
Parent();
433 typeDefTargetCursor.
AsCursor().GoToRoot();
434 if( newScopeParentCursor == scopeParentCursor )
436 scopeParentCursor= newScopeParentCursor;
440 if (typeDefTargetCursor.IsRoot()) {
441 Lox_Info(
"The type definition {!Q} was not found in the tag file {}:1. "
442 "While processing XLink {!Q}. This is probably an inherited type definition "
443 "to be resolved later",
445 return typeDefTargetCursor;
450 typeDefCursor= typeDefTargetCursor;
455 return typeDefTargetCursor;
464 for (
auto& baseTypeName : bases) {
478 if ( (baseType= index->Root()).AsCursor().GoTo(baseTypePath).IsEmpty() ) {
480 Lox_Error(
"The specified base entity {!Q} is not a record or a type defintion, but a {}. "
481 "Detected in tag-file {!Q}",
482 baseTypePath, baseType.
Kind(), index->FilePath )
495 Lox_Error(
"The specified base entity {!Q} does not exist in any tag-file.", baseTypeName)
504 if ( i>= previousResultSize && i < newResultSize )
518 bool starGiven =
false;
519 bool addFArgs =
false;
520 bool addTArgs =
false;
521 bool addSubscript =
false;
522 bool addType =
false;
523 bool addQualifiers =
false;
528 || display.
ConsumeChar(
'>') ) { addTArgs =
true;
continue; }
530 || display.
ConsumeChar(
')') ) { addFArgs =
true;
continue; }
532 || display.
ConsumeChar(
']') ) { addSubscript =
true;
continue; }
533 if ( display.
ConsumeChar(
'?') ) { addType =
true;
continue; }
534 if ( display.
ConsumeChar(
'!') ) { addQualifiers =
true;
continue; }
535 if ( display.
ConsumeChar(
'*') ) { starGiven =
true;
continue; }
541 addFArgs= addTArgs= addSubscript= addType= addQualifiers=
true;
567 if ( addFArgs | addTArgs | addSubscript | addType | addQualifiers )
581 ||
Result().IsIndirectByInheritance
582 ||
Result().IsResolvedTypeDef );
585 if ( display.
IsNotEmpty() && !addFArgs && !addTArgs && !addType && addParents < 2 ) {
597 rec && rec->TemplateArgs) {
599 newDisplay.
_(
"template ");
600 rec->TemplateArgs->Print(newDisplay);
601 newDisplay.
_<
NC>(
' ');
608 newDisplay << var->Type <<
' ';
610 func && func->Type.IsNotEmpty())
611 newDisplay << func->Type <<
' ';
621 for (
int i= addParents-2 ; i>= 0; --i) {
624 newDisplay <<
Scope(parentIdx);
638 int cntParentOverflow = 0;
639 for (; cntParentOverflow < addParents && !parent.IsRoot(); ++cntParentOverflow)
641 if ( parent.IsRoot() && cntParentOverflow < addParents)
644 n.Parent().Path(newDisplay, parent); }
647 if (prevDisplayLength != newDisplay.
Length()){
651 newDisplay.
_<
NC>(
"::");
656 newDisplay <<
Name();
666 if ( func->Args ) func->Args->Print(newDisplay);
667 else newDisplay.
_(
"()");
672 newDisplay.
_<
NC>(
' ')._<NC>(func->Qualifiers);
674 if (newDisplay.
EndsWith(
"noexcept") )
693 && (addSubscript ||
Subscript.IsNotNull()) )
694 newDisplay << Cast<TGTVariable,NC>(target)->Subscript;
698 newDisplay.
_<
NC>(
" (");
700 int cntParentOverflow = 0;
701 for (; cntParentOverflow < addParents && !parent.IsRoot(); ++cntParentOverflow)
702 parent= parent.Parent();
703 if ( parent.IsRoot() && cntParentOverflow < addParents)
707 newDisplay.
_<
NC>(
") ");
712 newDisplay << display;
718#if defined(TODO_IS_NEEDED_AGAIN)
743 integer scopeStart = fileName.StartsWith(
"struct") ? 6
744 : fileName.StartsWith(
"class") ? 5
745 : fileName.StartsWith(
"union") ? 5
746 : fileName.StartsWith(
"namespace") ? 9
747 : fileName.StartsWith(
"concept") ? 7
751 fileName.ShortenTo( fileName.LastIndexOf(
'.') );
754 fileName.DeleteStart(scopeStart);
755 fileName.SearchAndReplace(
"_8" ,
"@" );
756 fileName.SearchAndReplace(
"_1_1",
"@" );
757 fileName.SearchAndReplace(
"__" ,
"_" );
762 while (parser.IsNotEmpty() && scopeSize < MAX_SCOPE_DEPTH )
763 fileScope[scopeSize++]=
String( ma, parser.ConsumeToken(
'@') );
771 auto htmlFileHandle= htmlFile.
AsCursor().Export();
775 return std::make_pair(xl,
false);
797 return std::make_pair(xl,
true);
803 auto printType= [&](
const String& headLine,
const Index::Node& targetNode,
bool withPath) {
810 rec && rec->TemplateArgs )
813 bool isMember = targetNode.Parent()!=targetNode.Index().Root()
815 bool isConstructor= isMember
818 kindName= !isMember ?
"namespace-function"
819 : isConstructor ?
"constructor"
822 kindName= isMember ?
"member-variable" :
"namespace-variable";
824 rec && rec->SpecializationArgs )
825 kindName=
"specialization";
827 kindName= macro->Args ?
"preprocessor macro"
828 :
"preprocessor constant";
829 else kindName= target->
Kind();
846 if( typeCode) np.
_(
"(").
_(typeCode).
_(
") ");
852 rec && rec->TemplateArgs ) {
854 rec->TemplateArgs->Print(np);
857 if (withPath && !target->
IsA(
Target::Macro) && !targetNode.Parent().IsRoot()) {
860 targetNode.Parent().Path(pathBuf); }
861 np.
_(pathBuf).
_<
NC>(
"::");
864 String name= targetNode.Name();
872 if (
auto* rec=
Cast<TGTRecord>(target); rec && rec->SpecializationArgs )
873 rec->SpecializationArgs->Print(np);
876 np << var->Subscript;
879 macro->Args->Print(np);
881 String256 link(targetNode.Index().BaseURL);
884 link <<
'#' << mem->Anchor;
888 targetNode.Parent().Path(pathBuf);
889 np.
_<
NC>(
" in file: ")._<NC>(pathBuf);
895 out.
Add(
"{} {} {!ATab} {}:{} {!ATab} {} "
899 , targetNode.Index().FilePath
923 && !
Result().IsIndirectByInheritance
924 && !
Result().IsIndirectByTypeDef
925 && !
Result().IsIndirectLinkToScannedHTMLSourceFile ) {
926 out.
Add(
"Warning: XLink #{!Q} uses indirection prefix '^', while it targets a "
927 "direct member in the parent scope.\n"
928 " Hint: Remove the prefix from the XLink", linkString );
929 printType(
" Target:",
Result().Node,
true);
934 && (
Result().IsIndirectByInheritance
935 ||
Result().IsIndirectByTypeDef
936 ||
Result().IsIndirectLinkToScannedHTMLSourceFile ) ) {
937 out.
Add(
"Warning: XLink #{!Q} has an indirect target but is not marked with the "
938 "indirection prefix '^'.",
940 printType(
" Target:",
Result().Node,
true);
945 &&
Result().IsIndirectLinkToScannedHTMLSourceFile ) {
946 out.
Add(
"Warning: XLink #{!Q} links to an HTML-file found in the output folder "
947 "(not the tag file)!\n"
948 "Mark this link with indirection prefix '^' (to silence this warning).",
950 printType(
" Target:",
Result().Node,
true);
955 "No error to print for this valid XLink \"{}\" in the sources", linkString )
964 if (target.Node == it)
994 out.
Add(
"Ambiguous XLink #{!Q}.", linkString);
999 printType(
"Could be", target.Node,
true);
1007 printType(
"Could be", variable,
true);
1011 out.
Add(
"Further entities with the same name:");
1014 printType(
"", node,
true);
1022 out.
Add(
"Unresolved XLink #{!Q}.", linkString);
1033 ALIB_DBG(
MA.DbgCriticalSectionsPH->DCSLock=
nullptr;)
1035 out.
Buffer << (
" Given parent scope \"");
1041 out.
Buffer << (
"\" not found.\n");
1046 out.
Add(
"Collecting proposals of compound type(s) and base types: ");
1050 std::vector<Index::Node> parents;
1056 parents.push_back(target.Node);
1059 parents.push_back(target);
1062 parents.push_back(target);
1064 bool foundSimilar=
false;
1065 for (
int phase=0 ; phase<5 ; ++phase) {
1066 for (
auto& didYouMeanChildOf : parents) {
1074 auto child= didYouMeanChildOf.AsCursor().FirstChild();
1075 while ( child.IsValid() ) {
1078 && ( child.Name().StartsWith<CHK,lang::Case::Sensitive>(searchedName)
1079 || searchedName.
StartsWith<
CHK,lang::Case::Sensitive>(child.Name()) ) )
1081 && ( child.Name().StartsWith<CHK,lang::Case::Ignore >(searchedName)
1082 || searchedName.
StartsWith<
CHK,lang::Case::Ignore >(child.Name()) ) )
1084 && ( child.Name().IndexOf <NC,lang::Case::Sensitive>(searchedName) >=0
1085 || searchedName.
IndexOf <
NC,lang::Case::Sensitive>(child.Name()) >=0 ) )
1087 && ( child.Name().IndexOf <NC,lang::Case::Ignore >(searchedName) >=0
1088 || searchedName.
IndexOf <
NC,lang::Case::Ignore >(child.Name()) >=0 ) )
1092 if (!foundSimilar) {
1093 printType(
"Did you mean an entity in", didYouMeanChildOf,
true);
1096 printType(
" ", child,
false);
1098 child.GoToNextSibling();
1103 else if ( !foundSimilar) {
1104 auto child= didYouMeanChildOf.AsCursor().FirstChild();
1105 while (child.IsValid()) {
1107 if (!foundSimilar) {
1108 printType(
"Did you mean an entity in", didYouMeanChildOf,
true);
1111 printType(
" ", child,
false);
1113 child.GoToNextSibling();
1130 printType(
"Or ", indexCursor,
true);
1140 :
"Did you mean overloaded",
1147 printType(
"Subscript mismatch with: ", indexCursor,
true);
1152 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)