Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
Marco Bubke
flatpak-qt-creator
Commits
1932ffd1
Commit
1932ffd1
authored
Aug 03, 2010
by
Roberto Raggi
Browse files
Highlight the virtual methods.
parent
221cc387
Changes
6
Hide whitespace changes
Inline
Side-by-side
src/plugins/cppeditor/cppchecksymbols.cpp
View file @
1932ffd1
...
...
@@ -63,6 +63,7 @@ class CollectTypes: protected SymbolVisitor
Snapshot
_snapshot
;
QSet
<
QByteArray
>
_types
;
QSet
<
QByteArray
>
_members
;
QSet
<
QByteArray
>
_virtualMethods
;
QList
<
ScopedSymbol
*>
_scopes
;
QList
<
NameAST
*>
_names
;
bool
_mainDocument
;
...
...
@@ -85,6 +86,11 @@ public:
return
_members
;
}
const
QSet
<
QByteArray
>
&
virtualMethods
()
const
{
return
_virtualMethods
;
}
const
QList
<
ScopedSymbol
*>
&
scopes
()
const
{
return
_scopes
;
...
...
@@ -153,6 +159,18 @@ protected:
}
}
void
addVirtualMethod
(
const
Name
*
name
)
{
if
(
!
name
)
{
return
;
}
else
if
(
name
->
isNameId
())
{
const
Identifier
*
id
=
name
->
identifier
();
_virtualMethods
.
insert
(
QByteArray
::
fromRawData
(
id
->
chars
(),
id
->
size
()));
}
}
void
addScope
(
ScopedSymbol
*
symbol
)
{
if
(
_mainDocument
)
...
...
@@ -167,6 +185,9 @@ protected:
virtual
bool
visit
(
Function
*
symbol
)
{
if
(
symbol
->
isVirtual
())
addVirtualMethod
(
symbol
->
name
());
for
(
TemplateParameters
*
p
=
symbol
->
templateParameters
();
p
;
p
=
p
->
previous
())
{
Scope
*
scope
=
p
->
scope
();
for
(
unsigned
i
=
0
;
i
<
scope
->
symbolCount
();
++
i
)
...
...
@@ -191,6 +212,11 @@ protected:
virtual
bool
visit
(
Declaration
*
symbol
)
{
if
(
Function
*
funTy
=
symbol
->
type
()
->
asFunctionType
())
{
if
(
funTy
->
isVirtual
())
addVirtualMethod
(
symbol
->
name
());
}
if
(
symbol
->
isTypedef
())
addType
(
symbol
->
name
());
else
if
(
!
symbol
->
type
()
->
isFunctionType
()
&&
symbol
->
enclosingSymbol
()
->
isClass
())
...
...
@@ -298,6 +324,7 @@ CheckSymbols::CheckSymbols(Document::Ptr doc, const LookupContext &context)
CollectTypes
collectTypes
(
doc
,
context
.
snapshot
());
_potentialTypes
=
collectTypes
.
types
();
_potentialMembers
=
collectTypes
.
members
();
_potentialVirtualMethods
=
collectTypes
.
virtualMethods
();
_scopes
=
collectTypes
.
scopes
();
_flushRequested
=
false
;
_flushLine
=
0
;
...
...
@@ -370,8 +397,23 @@ bool CheckSymbols::visit(UsingDirectiveAST *)
return
true
;
}
bool
CheckSymbols
::
visit
(
SimpleDeclarationAST
*
)
{
bool
CheckSymbols
::
visit
(
SimpleDeclarationAST
*
ast
)
{
if
(
ast
->
declarator_list
&&
!
ast
->
declarator_list
->
next
)
{
if
(
ast
->
symbols
&&
!
ast
->
symbols
->
next
&&
!
ast
->
symbols
->
value
->
isGenerated
())
{
Symbol
*
decl
=
ast
->
symbols
->
value
;
if
(
NameAST
*
declId
=
declaratorId
(
ast
->
declarator_list
->
value
))
{
if
(
Function
*
funTy
=
decl
->
type
()
->
asFunctionType
())
{
if
(
funTy
->
isVirtual
())
{
addVirtualMethodUsage
(
declId
);
}
else
if
(
maybeVirtualMethod
(
decl
->
name
()))
{
addVirtualMethodUsage
(
_context
.
lookup
(
decl
->
name
(),
decl
->
scope
()),
declId
,
funTy
->
argumentCount
());
}
}
}
}
}
return
true
;
}
...
...
@@ -405,6 +447,52 @@ bool CheckSymbols::visit(MemberAccessAST *ast)
return
false
;
}
bool
CheckSymbols
::
visit
(
CallAST
*
ast
)
{
if
(
ast
->
base_expression
)
{
accept
(
ast
->
base_expression
);
unsigned
argumentCount
=
0
;
for
(
ExpressionListAST
*
it
=
ast
->
expression_list
;
it
;
it
=
it
->
next
)
++
argumentCount
;
if
(
MemberAccessAST
*
access
=
ast
->
base_expression
->
asMemberAccess
())
{
if
(
access
->
member_name
&&
access
->
member_name
->
name
)
{
if
(
maybeVirtualMethod
(
access
->
member_name
->
name
))
{
Scope
*
scope
=
findScope
(
access
);
const
QByteArray
expression
=
textOf
(
access
);
const
QList
<
LookupItem
>
candidates
=
typeOfExpression
(
expression
,
scope
,
TypeOfExpression
::
Preprocess
);
addVirtualMethodUsage
(
candidates
,
access
->
member_name
,
argumentCount
);
}
}
}
else
if
(
IdExpressionAST
*
idExpr
=
ast
->
base_expression
->
asIdExpression
())
{
if
(
const
Name
*
name
=
idExpr
->
name
->
name
)
{
if
(
maybeVirtualMethod
(
name
))
{
Scope
*
scope
=
findScope
(
idExpr
);
const
QByteArray
expression
=
textOf
(
idExpr
);
const
QList
<
LookupItem
>
candidates
=
typeOfExpression
(
expression
,
scope
,
TypeOfExpression
::
Preprocess
);
addVirtualMethodUsage
(
candidates
,
idExpr
->
name
,
argumentCount
);
}
}
}
accept
(
ast
->
expression_list
);
}
return
false
;
}
QByteArray
CheckSymbols
::
textOf
(
AST
*
ast
)
const
{
const
Token
start
=
tokenAt
(
ast
->
firstToken
());
const
Token
end
=
tokenAt
(
ast
->
lastToken
()
-
1
);
const
QByteArray
text
=
_doc
->
source
().
mid
(
start
.
begin
(),
end
.
end
()
-
start
.
begin
());
return
text
;
}
void
CheckSymbols
::
checkNamespace
(
NameAST
*
name
)
{
if
(
!
name
)
...
...
@@ -573,6 +661,21 @@ bool CheckSymbols::visit(FunctionDefinitionAST *ast)
_functionDefinitionStack
.
append
(
ast
);
accept
(
ast
->
decl_specifier_list
);
if
(
ast
->
declarator
&&
!
ast
->
symbol
->
isGenerated
())
{
Function
*
fun
=
ast
->
symbol
;
if
(
NameAST
*
declId
=
declaratorId
(
ast
->
declarator
))
{
if
(
QualifiedNameAST
*
q
=
declId
->
asQualifiedName
())
declId
=
q
->
unqualified_name
;
if
(
fun
->
isVirtual
())
{
addVirtualMethodUsage
(
declId
);
}
else
if
(
maybeVirtualMethod
(
fun
->
name
()))
{
addVirtualMethodUsage
(
_context
.
lookup
(
fun
->
name
(),
fun
->
scope
()),
declId
,
fun
->
argumentCount
());
}
}
}
accept
(
ast
->
declarator
);
accept
(
ast
->
ctor_initializer
);
accept
(
ast
->
function_body
);
...
...
@@ -687,8 +790,61 @@ void CheckSymbols::addMemberUsage(const QList<LookupItem> &candidates, NameAST *
const
Use
use
(
line
,
column
,
length
,
Use
::
Field
);
addUsage
(
use
);
//Overview oo;
//qDebug() << "added use" << oo(ast->name) << line << column << length;
break
;
}
}
void
CheckSymbols
::
addVirtualMethodUsage
(
NameAST
*
ast
)
{
if
(
!
ast
)
return
;
unsigned
startToken
=
ast
->
firstToken
();
if
(
DestructorNameAST
*
dtor
=
ast
->
asDestructorName
())
startToken
=
dtor
->
identifier_token
;
const
Token
&
tok
=
tokenAt
(
startToken
);
if
(
tok
.
generated
())
return
;
unsigned
line
,
column
;
getTokenStartPosition
(
startToken
,
&
line
,
&
column
);
const
unsigned
length
=
tok
.
length
();
const
Use
use
(
line
,
column
,
length
,
Use
::
VirtualMethod
);
addUsage
(
use
);
}
void
CheckSymbols
::
addVirtualMethodUsage
(
const
QList
<
LookupItem
>
&
candidates
,
NameAST
*
ast
,
unsigned
argumentCount
)
{
unsigned
startToken
=
ast
->
firstToken
();
if
(
DestructorNameAST
*
dtor
=
ast
->
asDestructorName
())
startToken
=
dtor
->
identifier_token
;
const
Token
&
tok
=
tokenAt
(
startToken
);
if
(
tok
.
generated
())
return
;
unsigned
line
,
column
;
getTokenStartPosition
(
startToken
,
&
line
,
&
column
);
const
unsigned
length
=
tok
.
length
();
foreach
(
const
LookupItem
&
r
,
candidates
)
{
Symbol
*
c
=
r
.
declaration
();
if
(
!
c
)
continue
;
Function
*
funTy
=
r
.
type
()
->
asFunctionType
();
if
(
!
funTy
)
continue
;
if
(
!
funTy
->
isVirtual
())
continue
;
else
if
(
argumentCount
<
funTy
->
minimumArgumentCount
())
continue
;
const
Use
use
(
line
,
column
,
length
,
Use
::
VirtualMethod
);
addUsage
(
use
);
break
;
}
}
...
...
@@ -723,6 +879,30 @@ Scope *CheckSymbols::findScope(AST *ast) const
return
scope
;
}
NameAST
*
CheckSymbols
::
declaratorId
(
DeclaratorAST
*
ast
)
const
{
if
(
ast
&&
ast
->
core_declarator
)
{
if
(
NestedDeclaratorAST
*
nested
=
ast
->
core_declarator
->
asNestedDeclarator
())
return
declaratorId
(
nested
->
declarator
);
else
if
(
DeclaratorIdAST
*
declId
=
ast
->
core_declarator
->
asDeclaratorId
())
{
return
declId
->
name
;
}
}
return
0
;
}
bool
CheckSymbols
::
maybeVirtualMethod
(
const
Name
*
name
)
const
{
if
(
const
Identifier
*
ident
=
name
->
identifier
())
{
const
QByteArray
id
=
QByteArray
::
fromRawData
(
ident
->
chars
(),
ident
->
size
());
if
(
_potentialVirtualMethods
.
contains
(
id
))
return
true
;
}
return
false
;
}
void
CheckSymbols
::
flush
()
{
_flushRequested
=
false
;
...
...
src/plugins/cppeditor/cppchecksymbols.h
View file @
1932ffd1
...
...
@@ -93,6 +93,8 @@ protected:
bool
warning
(
unsigned
line
,
unsigned
column
,
const
QString
&
text
,
unsigned
length
=
0
);
bool
warning
(
AST
*
ast
,
const
QString
&
text
);
QByteArray
textOf
(
AST
*
ast
)
const
;
void
checkName
(
NameAST
*
ast
,
Scope
*
scope
=
0
);
void
checkNamespace
(
NameAST
*
name
);
void
addUsage
(
ClassOrNamespace
*
b
,
NameAST
*
ast
);
...
...
@@ -101,6 +103,10 @@ protected:
void
checkMemberName
(
NameAST
*
ast
);
void
addMemberUsage
(
const
QList
<
LookupItem
>
&
candidates
,
NameAST
*
ast
);
void
addVirtualMethodUsage
(
const
QList
<
LookupItem
>
&
candidates
,
NameAST
*
ast
,
unsigned
argumentCount
);
void
addVirtualMethodUsage
(
NameAST
*
ast
);
bool
maybeVirtualMethod
(
const
Name
*
name
)
const
;
virtual
bool
preVisit
(
AST
*
);
...
...
@@ -122,9 +128,12 @@ protected:
virtual
bool
visit
(
FunctionDefinitionAST
*
ast
);
virtual
bool
visit
(
MemberAccessAST
*
ast
);
virtual
bool
visit
(
CallAST
*
ast
);
virtual
bool
visit
(
MemInitializerAST
*
ast
);
NameAST
*
declaratorId
(
DeclaratorAST
*
ast
)
const
;
unsigned
startOfTemplateDeclaration
(
TemplateDeclarationAST
*
ast
)
const
;
Scope
*
findScope
(
AST
*
ast
)
const
;
...
...
@@ -138,6 +147,7 @@ private:
QList
<
Document
::
DiagnosticMessage
>
_diagnosticMessages
;
QSet
<
QByteArray
>
_potentialTypes
;
QSet
<
QByteArray
>
_potentialMembers
;
QSet
<
QByteArray
>
_potentialVirtualMethods
;
QList
<
ScopedSymbol
*>
_scopes
;
QList
<
TemplateDeclarationAST
*>
_templateDeclarationStack
;
QList
<
FunctionDefinitionAST
*>
_functionDefinitionStack
;
...
...
src/plugins/cppeditor/cppeditor.cpp
View file @
1932ffd1
...
...
@@ -968,6 +968,9 @@ void CPPEditor::highlightTypeUsages(int from, int to)
Q_ASSERT
(
!
chunks
.
isEmpty
());
QTextBlock
b
=
doc
->
findBlockByNumber
(
m_nextHighlightBlockNumber
);
QTextCharFormat
virtualMethodFormat
;
// ### hardcoded;
virtualMethodFormat
.
setFontItalic
(
true
);
QMapIterator
<
int
,
QVector
<
SemanticInfo
::
Use
>
>
it
(
chunks
);
while
(
b
.
isValid
()
&&
it
.
hasNext
())
{
it
.
next
();
...
...
@@ -997,6 +1000,10 @@ void CPPEditor::highlightTypeUsages(int from, int to)
formatRange
.
format
=
m_localFormat
;
break
;
case
SemanticInfo
::
Use
::
VirtualMethod
:
formatRange
.
format
=
virtualMethodFormat
;
break
;
default:
continue
;
}
...
...
src/plugins/cppeditor/cppsemanticinfo.h
View file @
1932ffd1
...
...
@@ -51,7 +51,8 @@ public:
enum
{
Type
=
0
,
Local
,
Field
Field
,
VirtualMethod
};
Use
(
unsigned
line
=
0
,
unsigned
column
=
0
,
unsigned
length
=
0
,
unsigned
kind
=
Type
)
...
...
src/shared/cplusplus/Symbols.cpp
View file @
1932ffd1
...
...
@@ -352,6 +352,20 @@ bool Function::hasArguments() const
(
argumentCount
()
==
1
&&
argumentAt
(
0
)
->
type
()
->
isVoidType
()));
}
unsigned
Function
::
minimumArgumentCount
()
const
{
unsigned
index
=
0
;
for
(;
index
<
_arguments
->
symbolCount
();
++
index
)
{
if
(
Argument
*
arg
=
_arguments
->
symbolAt
(
index
)
->
asArgument
())
{
if
(
arg
->
hasInitializer
())
break
;
}
}
return
index
;
}
bool
Function
::
isVirtual
()
const
{
return
f
.
_isVirtual
;
}
...
...
src/shared/cplusplus/Symbols.h
View file @
1932ffd1
...
...
@@ -360,6 +360,7 @@ public:
/** Convenience function that returns whether the function receives any arguments. */
bool
hasArguments
()
const
;
unsigned
minimumArgumentCount
()
const
;
bool
isVirtual
()
const
;
void
setVirtual
(
bool
isVirtual
);
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment