work save

This commit is contained in:
royqh1979@gmail.com 2021-08-18 21:57:42 +08:00
parent d18347c44e
commit c9a21b8a03
3 changed files with 160 additions and 68 deletions

View File

@ -1114,13 +1114,15 @@ void CppParser::handleOtherTypedefs()
while(true) {
oldType += mTokenizer[mIndex]->text + ' ';
mIndex++;
if ((mIndex + 1 < mTokenizer.tokenCount())
&& (mTokenizer[mIndex + 1]->text.front() == ','
|| mTokenizer[mIndex + 1]->text.front() == ';'))
if (mIndex+1>=mTokenizer.tokenCount())
break;
if (mTokenizer[mIndex + 1]->text.front() == ','
|| mTokenizer[mIndex + 1]->text.front() == ';')
break;
if ((mIndex + 2 < mTokenizer.tokenCount())
&& (mTokenizer[mIndex + 2]->text.front() == ','
|| mTokenizer[mIndex + 2]->text.front() == ';'))
&& (mTokenizer[mIndex + 2]->text.front() == ','
|| mTokenizer[mIndex + 2]->text.front() == ';')
&& (mTokenizer[mIndex + 1]->text.front() == '('))
break;
}
oldType = oldType.trimmed();
@ -1128,76 +1130,134 @@ void CppParser::handleOtherTypedefs()
// Add synonyms for old
if ((mIndex+1 < mTokenizer.tokenCount()) && !oldType.isEmpty()) {
QString newType;
while(true) {
// Support multiword typedefs
if (mIndex+2 < mTokenizer.tokenCount()) and (mTokenizer[mIndex + 2]->text[1] in [',', ';']) then begin // function define
if (mIndex + 2 < mTokenizer.tokenCount()) and (mIndex + 1 < mTokenizer.tokenCount()) and (mTokenizer[mIndex + 1]->text[1] = '(') then begin
if ((mIndex + 2 < mTokenizer.tokenCount())
&& (mTokenizer[mIndex + 2]->text.front() == ','
|| mTokenizer[mIndex + 2]->text.front() == ';')
&& (mTokenizer[mIndex + 1]->text.front() == '(')) {
//valid function define
NewType:=TrimRight(mTokenizer[mIndex]->text);
NewType:=Copy(NewType,2,Length(NewType)-2); //remove '(' and ')';
NewType:=TrimRight(NewType);
p:=LastDelimiter(' ',NewType);
if p <> 0 then
NewType := Copy(NewType,p+1,Length(NewType)-p);
AddStatement(
GetCurrentScope,
fCurrentFile,
'typedef ' + OldType + ' ' + mTokenizer[mIndex]->text + ' ' + mTokenizer[mIndex + 1]->text, // do not override hint
OldType,
NewType,
mTokenizer[mIndex + 1]->text,
'',
startLine,
skTypedef,
GetScope,
fClassScope,
True,
nil,
False);
end;
NewType:='';
//skip to ',' or ';'
Inc(mIndex,2);
{
while (mIndex< mTokenizer.tokenCount()) and not (mTokenizer[mIndex]->text[1] in [',', ';']) do
Inc(mIndex);
}
end else if not (mTokenizer[mIndex+1]->text[1] in [',', ';', '(']) then begin
NewType := NewType + mTokenizer[mIndex]->text + ' ';
Inc(mIndex);
end else begin
NewType := NewType + mTokenizer[mIndex]->text + ' ';
NewType := TrimRight(NewType);
AddStatement(
GetCurrentScope,
fCurrentFile,
'typedef ' + OldType + ' ' + NewType, // override hint
OldType,
NewType,
'',
'',
//mTokenizer[mIndex]^.Line,
startLine,
skTypedef,
GetScope,
fClassScope,
True,
nil,
False);
NewType := '';
Inc(mIndex);
end;
if (mIndex>= mTokenizer.tokenCount()) or (mTokenizer[mIndex]->text[1] = ';') then
break
else if mTokenizer[mIndex]->text[1] = ',' then
Inc(mIndex);
newType = mTokenizer[mIndex]->text.trimmed();
newType = newType.mid(1,newType.length()-2); //remove '(' and ')';
newType = newType.trimmed();
int p = newType.lastIndexOf(' ');
if (p>=0)
newType.truncate(p+1);
addStatement(
getCurrentScope(),
mCurrentFile,
"typedef " + oldType + " " + mTokenizer[mIndex]->text + " " +
mTokenizer[mIndex + 1]->text, // do not override hint
oldType,
newType,
mTokenizer[mIndex + 1]->text,
"",
startLine,
StatementKind::skTypedef,
getScope(),
mClassScope,
true,
false);
newType = "";
//skip to ',' or ';'
mIndex+=2;
} else if (mTokenizer[mIndex+1]->text.front() ==','
|| mTokenizer[mIndex+1]->text.front() ==';'
|| mTokenizer[mIndex+1]->text.front() =='(') {
newType += mTokenizer[mIndex]->text;
newType = newType.trimmed();
addStatement(
getCurrentScope(),
mCurrentFile,
"typedef " + oldType + " " + newType, // override hint
oldType,
newType,
"",
"",
startLine,
StatementKind::skTypedef,
getScope(),
mClassScope,
true,
false);
newType = "";
mIndex++;
} else {
newType += mTokenizer[mIndex]->text + ' ';
mIndex++;
}
if ((mIndex>= mTokenizer.tokenCount()) || (mTokenizer[mIndex]->text[1] == ';'))
break;
else if (mTokenizer[mIndex]->text.front() == ',')
mIndex++;
if (mIndex+1 >= mTokenizer.tokenCount())
break;
}
}
// Step over semicolon (saves one HandleStatement loop)
Inc(mIndex);
// Step over semicolon (saves one HandleStatement loop)
mIndex++;
}
void
void CppParser::handlePreprocessor()
{
if (mTokenizer[mIndex]->text.startsWith("#include ")) { // start of new file
// format: #include fullfilename:line
// Strip keyword
QString s = mTokenizer[mIndex]->text.mid(QString("#include ").length());
int delimPos = s.lastIndexOf(':');
if (delimPos>=0) {
mCurrentFile = s.mid(0,delimPos);
mIsSystemHeader = isSystemHeaderFile(mCurrentFile) || isProjectHeaderFile(mCurrentFile);
mIsProjectFile = mProjectFiles.contains(mCurrentFile); FastIndexOf(fProjectFiles,fCurrentFile) <> -1;
mIsHeader = isHfile(mCurrentFile);
// Mention progress to user if we enter a NEW file
bool ok;
int line = s.mid(delimPos+1).toInt(&ok);
if (line == 1) {
mFilesScannedCount++;
mFilesToScanCount++;
onProgress(mCurrentFile,mFilesToScanCount,mFilesScannedCount);
}
}
} else if (mTokenizer[mIndex]->text.startsWith("#define ")) {
// format: #define A B, remove define keyword
QString s = mTokenizer[mIndex]->text.mid(QString("#define ").length());
// Ask the preprocessor to cut parts up
QString name,args,value;
mPreprocessor.getDefineParts(s,name,args,value);
// Generate custom hint
QString hintText = "#define";
if (!name.isEmpty())
hintText += ' ' + name;
if (!args.isEmpty())
hintText += ' ' + args;
if (!value.isEmpty())
hintText += ' ' + value;
addStatement(
nullptr, // defines don't belong to any scope
mCurrentFile,
hintText, // override hint
"", // define has no type
name,
args,
value,
mTokenizer[mIndex]->line,
StatementKind::skPreprocessor,
StatementScope::ssGlobal,
StatementClassScope::scsNone,
true,
false);
} // TODO: undef ( define has limited scope)
mIndex++;
}
QString CppParser::expandMacroType(const QString &name)
@ -1367,6 +1427,11 @@ QString CppParser::removeArgNames(const QString &args)
return result;
}
void CppParser::removeDefine(const QString &name)
{
}
bool CppParser::isSpaceChar(const QChar &ch)
{
return ch==' ' || ch =='\t';

View File

@ -12,8 +12,25 @@ QSet<QString> STLPointers;
QSet<QString> STLContainers;
QSet<QString> STLElementMethods;
static QSet<QString> CppHeaderExts;
static QSet<QString> CppSourceExts;
void initParser()
{
CppHeaderExts.insert("h");
CppHeaderExts.insert("hpp");
CppHeaderExts.insert("rh");
CppHeaderExts.insert("hh");
CppHeaderExts.insert("hxx");
CppHeaderExts.insert("inl");
CppHeaderExts.insert("");
CppSourceExts.insert("c");
CppSourceExts.insert("cpp");
CppSourceExts.insert("cc");
CppSourceExts.insert("cxx");
CppSourceExts.insert("c++");
CppSourceExts.insert("cp");
// skip itself
CppKeywords.insert("and",SkipType::skItself);
CppKeywords.insert("and_eq",SkipType::skItself);
@ -333,3 +350,13 @@ bool isKeyword(const QString &word)
{
return CppKeywords.contains(word);
}
bool isHfile(const QString filename)
{
if (filename.isEmpty())
return false;
QFileInfo fileInfo(filename);
return CppHeaderExts.contains(fileInfo.suffix().toLower());
}

View File

@ -169,6 +169,6 @@ QString getLocalHeaderFileName(const QString& relativeTo, const QString& fileNam
QString getSystemHeaderFileName(const QString& fileName, const QStringList& includePaths);
bool isSystemHeaderFile(const QString& fileName, const QStringList& includePaths);
bool isHfile(const QString filename);
bool isKeyword(const QString& word);
#endif // PARSER_UTILS_H