You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
328 lines
9.3 KiB
328 lines
9.3 KiB
/*
|
|
* Copyright 2018 Google Inc.
|
|
*
|
|
* Use of this source code is governed by a BSD-style license that can be
|
|
* found in the LICENSE file.
|
|
*/
|
|
|
|
#ifndef definition_DEFINED
|
|
#define definition_DEFINED
|
|
|
|
#include "textParser.h"
|
|
|
|
class RootDefinition;
|
|
class TextParser;
|
|
|
|
class Definition : public NonAssignable {
|
|
public:
|
|
enum Type {
|
|
kNone,
|
|
kWord,
|
|
kMark,
|
|
kKeyWord,
|
|
kBracket,
|
|
kPunctuation,
|
|
kFileType,
|
|
};
|
|
|
|
enum class MethodType {
|
|
kNone,
|
|
kConstructor,
|
|
kDestructor,
|
|
kOperator,
|
|
};
|
|
|
|
enum class Operator {
|
|
kUnknown,
|
|
kAdd,
|
|
kAddTo,
|
|
kArray,
|
|
kCast,
|
|
kCopy,
|
|
kDelete,
|
|
kDereference,
|
|
kEqual,
|
|
kMinus,
|
|
kMove,
|
|
kMultiply,
|
|
kMultiplyBy,
|
|
kNew,
|
|
kNotEqual,
|
|
kSubtract,
|
|
kSubtractFrom,
|
|
};
|
|
|
|
enum class Format {
|
|
kIncludeReturn,
|
|
kOmitReturn,
|
|
};
|
|
|
|
enum class Details {
|
|
kNone,
|
|
kSoonToBe_Deprecated,
|
|
kTestingOnly_Experiment,
|
|
kDoNotUse_Experiment,
|
|
kNotReady_Experiment,
|
|
};
|
|
|
|
enum class DetailsType {
|
|
kPhrase,
|
|
kSentence,
|
|
};
|
|
|
|
Definition() {}
|
|
|
|
Definition(const char* start, const char* end, int line, Definition* parent, char mc)
|
|
: fStart(start)
|
|
, fContentStart(start)
|
|
, fContentEnd(end)
|
|
, fParent(parent)
|
|
, fLineCount(line)
|
|
, fType(Type::kWord)
|
|
, fMC(mc) {
|
|
if (parent) {
|
|
SkASSERT(parent->fFileName.length() > 0);
|
|
fFileName = parent->fFileName;
|
|
}
|
|
this->setParentIndex();
|
|
}
|
|
|
|
Definition(MarkType markType, const char* start, int line, Definition* parent, char mc)
|
|
: Definition(markType, start, nullptr, line, parent, mc) {
|
|
}
|
|
|
|
Definition(MarkType markType, const char* start, const char* end, int line, Definition* parent, char mc)
|
|
: Definition(start, end, line, parent, mc) {
|
|
fMarkType = markType;
|
|
fType = Type::kMark;
|
|
}
|
|
|
|
Definition(Bracket bracket, const char* start, int lineCount, Definition* parent, char mc)
|
|
: Definition(start, nullptr, lineCount, parent, mc) {
|
|
fBracket = bracket;
|
|
fType = Type::kBracket;
|
|
}
|
|
|
|
Definition(KeyWord keyWord, const char* start, const char* end, int lineCount,
|
|
Definition* parent, char mc)
|
|
: Definition(start, end, lineCount, parent, mc) {
|
|
fKeyWord = keyWord;
|
|
fType = Type::kKeyWord;
|
|
}
|
|
|
|
Definition(Punctuation punctuation, const char* start, int lineCount, Definition* parent, char mc)
|
|
: Definition(start, nullptr, lineCount, parent, mc) {
|
|
fPunctuation = punctuation;
|
|
fType = Type::kPunctuation;
|
|
}
|
|
|
|
virtual ~Definition() {}
|
|
|
|
virtual RootDefinition* asRoot() { SkASSERT(0); return nullptr; }
|
|
bool boilerplateIfDef();
|
|
|
|
bool boilerplateEndIf() {
|
|
return true;
|
|
}
|
|
|
|
bool checkMethod() const;
|
|
bool crossCheck2(const Definition& includeToken) const;
|
|
bool crossCheck(const Definition& includeToken) const;
|
|
bool crossCheckInside(const char* start, const char* end, const Definition& includeToken) const;
|
|
|
|
Definition* csParent() {
|
|
Definition* test = fParent;
|
|
while (test) {
|
|
if (MarkType::kStruct == test->fMarkType || MarkType::kClass == test->fMarkType) {
|
|
return test;
|
|
}
|
|
test = test->fParent;
|
|
}
|
|
return nullptr;
|
|
}
|
|
|
|
string fiddleName() const;
|
|
string fileName() const;
|
|
const Definition* findClone(string match) const;
|
|
string formatFunction(Format format) const;
|
|
const Definition* hasChild(MarkType markType) const;
|
|
bool hasMatch(string name) const;
|
|
Definition* hasParam(string ref);
|
|
bool isClone() const { return fClone; }
|
|
|
|
const Definition* iRootParent() const {
|
|
const Definition* test = fParent;
|
|
while (test) {
|
|
if (KeyWord::kClass == test->fKeyWord || KeyWord::kStruct == test->fKeyWord) {
|
|
return test;
|
|
}
|
|
test = test->fParent;
|
|
}
|
|
return nullptr;
|
|
}
|
|
|
|
virtual bool isRoot() const { return false; }
|
|
bool isStructOrClass() const;
|
|
|
|
int length() const {
|
|
return (int) (fContentEnd - fContentStart);
|
|
}
|
|
|
|
const char* methodEnd() const;
|
|
bool methodHasReturn(string name, TextParser* methodParser) const;
|
|
string methodName() const;
|
|
bool nextMethodParam(TextParser* methodParser, const char** nextEndPtr,
|
|
string* paramName) const;
|
|
static string NormalizedName(string name);
|
|
bool paramsMatch(string fullRef, string name) const;
|
|
bool parseOperator(size_t doubleColons, string& result);
|
|
|
|
string printableName() const {
|
|
string result(fName);
|
|
std::replace(result.begin(), result.end(), '_', ' ');
|
|
return result;
|
|
}
|
|
|
|
template <typename T> T reportError(const char* errorStr) const {
|
|
TextParser tp(this);
|
|
tp.reportError(errorStr);
|
|
return T();
|
|
}
|
|
|
|
virtual RootDefinition* rootParent() { SkASSERT(0); return nullptr; }
|
|
virtual const RootDefinition* rootParent() const { SkASSERT(0); return nullptr; }
|
|
void setCanonicalFiddle();
|
|
|
|
void setParentIndex() {
|
|
fParentIndex = fParent ? (int) fParent->fTokens.size() : -1;
|
|
}
|
|
|
|
static bool SkipImplementationWords(TextParser& inc);
|
|
|
|
string simpleName() {
|
|
size_t doubleColon = fName.rfind("::");
|
|
return string::npos == doubleColon ? fName : fName.substr(doubleColon + 2);
|
|
}
|
|
|
|
const Definition* subtopicParent() const {
|
|
Definition* test = fParent;
|
|
while (test) {
|
|
if (MarkType::kTopic == test->fMarkType || MarkType::kSubtopic == test->fMarkType) {
|
|
return test;
|
|
}
|
|
test = test->fParent;
|
|
}
|
|
return nullptr;
|
|
}
|
|
|
|
const Definition* topicParent() const {
|
|
Definition* test = fParent;
|
|
while (test) {
|
|
if (MarkType::kTopic == test->fMarkType) {
|
|
return test;
|
|
}
|
|
test = test->fParent;
|
|
}
|
|
return nullptr;
|
|
}
|
|
|
|
void trimEnd();
|
|
|
|
string fText; // if text is constructed instead of in a file, it's put here
|
|
const char* fStart = nullptr; // .. in original text file, or the start of fText
|
|
const char* fContentStart; // start past optional markup name
|
|
string fName;
|
|
string fFiddle; // if its a constructor or operator, fiddle name goes here
|
|
string fCode; // suitable for autogeneration of #Code blocks in bmh
|
|
const char* fContentEnd = nullptr; // the end of the contained text
|
|
const char* fTerminator = nullptr; // the end of the markup, normally ##\n or \n
|
|
Definition* fParent = nullptr;
|
|
list<Definition> fTokens;
|
|
vector<Definition*> fChildren;
|
|
string fHash; // generated by fiddle
|
|
string fFileName;
|
|
mutable string fWrapper; // used by Example to wrap into proper function
|
|
size_t fLineCount = 0;
|
|
int fParentIndex = 0;
|
|
MarkType fMarkType = MarkType::kNone;
|
|
KeyWord fKeyWord = KeyWord::kNone;
|
|
Bracket fBracket = Bracket::kNone;
|
|
Punctuation fPunctuation = Punctuation::kNone;
|
|
MethodType fMethodType = MethodType::kNone;
|
|
Operator fOperator = Operator::kUnknown;
|
|
Type fType = Type::kNone;
|
|
char fMC = '#';
|
|
bool fClone = false;
|
|
bool fCloned = false;
|
|
bool fOperatorConst = false;
|
|
bool fPrivate = false;
|
|
Details fDetails = Details::kNone;
|
|
bool fMemberStart = false;
|
|
bool fAnonymous = false;
|
|
bool fUndocumented = false; // include symbol comment has deprecated, private, experimental
|
|
mutable bool fVisited = false;
|
|
};
|
|
|
|
class RootDefinition : public Definition {
|
|
public:
|
|
enum class AllowParens {
|
|
kNo,
|
|
kYes,
|
|
};
|
|
|
|
struct SubtopicContents {
|
|
SubtopicContents()
|
|
: fShowClones(false) {
|
|
}
|
|
|
|
vector<Definition*> fMembers;
|
|
bool fShowClones;
|
|
};
|
|
|
|
RootDefinition() {
|
|
}
|
|
|
|
RootDefinition(MarkType markType, const char* start, int line, Definition* parent, char mc)
|
|
: Definition(markType, start, line, parent, mc) {
|
|
if (MarkType::kSubtopic != markType && MarkType::kTopic != markType) {
|
|
if (parent) {
|
|
fNames.fName = parent->fName;
|
|
fNames.fParent = &parent->asRoot()->fNames;
|
|
}
|
|
}
|
|
}
|
|
|
|
RootDefinition(MarkType markType, const char* start, const char* end, int line,
|
|
Definition* parent, char mc) : Definition(markType, start, end, line, parent, mc) {
|
|
}
|
|
|
|
~RootDefinition() override {
|
|
for (auto& iter : fBranches) {
|
|
delete iter.second;
|
|
}
|
|
}
|
|
|
|
RootDefinition* asRoot() override { return this; }
|
|
void clearVisited();
|
|
bool dumpUnVisited();
|
|
Definition* find(string ref, AllowParens );
|
|
bool isRoot() const override { return true; }
|
|
|
|
SubtopicContents& populator(const char* key) {
|
|
return fPopulators[key];
|
|
}
|
|
|
|
RootDefinition* rootParent() override { return fRootParent; }
|
|
const RootDefinition* rootParent() const override { return fRootParent; }
|
|
void setRootParent(RootDefinition* rootParent) { fRootParent = rootParent; }
|
|
|
|
unordered_map<string, RootDefinition*> fBranches;
|
|
unordered_map<string, Definition> fLeaves;
|
|
unordered_map<string, SubtopicContents> fPopulators;
|
|
NameMap fNames;
|
|
private:
|
|
RootDefinition* fRootParent = nullptr;
|
|
};
|
|
|
|
#endif
|