Skip to content
GitLab
Menu
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
c282da7d
Commit
c282da7d
authored
May 11, 2010
by
Roberto Raggi
Browse files
Introduced Snapshot::findMatchingDefinition().
parent
7eae5150
Changes
6
Hide whitespace changes
Inline
Side-by-side
src/libs/cplusplus/CppDocument.cpp
View file @
c282da7d
...
...
@@ -29,6 +29,8 @@
#include "CppDocument.h"
#include "FastPreprocessor.h"
#include "LookupContext.h"
#include "Overview.h"
#include <Control.h>
#include <TranslationUnit.h>
...
...
@@ -36,8 +38,10 @@
#include <Semantic.h>
#include <Literals.h>
#include <Symbols.h>
#include <Names.h>
#include <AST.h>
#include <Scope.h>
#include <SymbolVisitor.h>
#include <QtCore/QByteArray>
#include <QtCore/QBitArray>
...
...
@@ -570,3 +574,120 @@ void Snapshot::simplified_helper(Document::Ptr doc, Snapshot *snapshot) const
}
}
}
namespace
{
class
FindMatchingDefinition
:
public
SymbolVisitor
{
Symbol
*
_declaration
;
QList
<
Function
*>
_result
;
public:
FindMatchingDefinition
(
Symbol
*
declaration
)
:
_declaration
(
declaration
)
{}
QList
<
Function
*>
result
()
const
{
return
_result
;
}
using
SymbolVisitor
::
visit
;
virtual
bool
visit
(
Function
*
fun
)
{
if
(
_declaration
->
identifier
()
->
isEqualTo
(
fun
->
identifier
()))
_result
.
append
(
fun
);
return
false
;
}
virtual
bool
visit
(
Block
*
)
{
return
false
;
}
};
}
// end of anonymous namespace
Symbol
*
Snapshot
::
findMatchingDefinition
(
Symbol
*
symbol
)
const
{
if
(
!
symbol
->
identifier
())
return
0
;
Document
::
Ptr
thisDocument
=
document
(
QString
::
fromUtf8
(
symbol
->
fileName
(),
symbol
->
fileNameLength
()));
if
(
!
thisDocument
)
{
qWarning
()
<<
"undefined document:"
<<
symbol
->
fileName
();
return
0
;
}
LookupContext
thisContext
(
thisDocument
,
*
this
);
const
QList
<
Symbol
*>
declarationCandidates
=
thisContext
.
lookup
(
symbol
->
name
(),
symbol
);
if
(
declarationCandidates
.
isEmpty
())
{
qWarning
()
<<
"unresolved declaration:"
<<
symbol
->
fileName
()
<<
symbol
->
line
()
<<
symbol
->
column
();
return
0
;
}
Symbol
*
declaration
=
declarationCandidates
.
first
();
Function
*
declarationTy
=
declaration
->
type
()
->
asFunctionType
();
if
(
!
declarationTy
)
{
qWarning
()
<<
"not a function:"
<<
declaration
->
fileName
()
<<
declaration
->
line
()
<<
declaration
->
column
();
return
0
;
}
foreach
(
Document
::
Ptr
doc
,
*
this
)
{
if
(
!
doc
->
control
()
->
findIdentifier
(
declaration
->
identifier
()
->
chars
(),
declaration
->
identifier
()
->
size
()))
continue
;
FindMatchingDefinition
candidates
(
declaration
);
candidates
.
accept
(
doc
->
globalNamespace
());
const
QList
<
Function
*>
result
=
candidates
.
result
();
if
(
!
result
.
isEmpty
())
{
LookupContext
context
(
doc
,
*
this
);
QList
<
Function
*>
viableFunctions
;
foreach
(
Function
*
fun
,
result
)
{
const
QList
<
Symbol
*>
declarations
=
context
.
lookup
(
fun
->
name
(),
fun
);
if
(
declarations
.
contains
(
declaration
))
viableFunctions
.
append
(
fun
);
else
if
(
false
)
qDebug
()
<<
"does not contain"
<<
declaration
->
fileName
()
<<
declaration
->
line
()
<<
declaration
->
column
();
}
if
(
viableFunctions
.
isEmpty
())
continue
;
else
if
(
viableFunctions
.
length
()
==
1
)
return
viableFunctions
.
first
();
Function
*
best
=
0
;
foreach
(
Function
*
fun
,
viableFunctions
)
{
if
(
fun
->
identity
()
->
isEqualTo
(
declaration
->
identity
()))
continue
;
else
if
(
fun
->
argumentCount
()
==
declarationTy
->
argumentCount
())
{
if
(
!
best
)
best
=
fun
;
unsigned
argc
=
0
;
for
(;
argc
<
declarationTy
->
argumentCount
();
++
argc
)
{
Symbol
*
arg
=
fun
->
argumentAt
(
argc
);
Symbol
*
otherArg
=
declarationTy
->
argumentAt
(
argc
);
if
(
!
arg
->
type
().
isEqualTo
(
otherArg
->
type
()))
break
;
}
if
(
argc
==
declarationTy
->
argumentCount
())
best
=
fun
;
}
}
if
(
!
best
)
best
=
viableFunctions
.
first
();
return
best
;
}
}
return
0
;
}
src/libs/cplusplus/CppDocument.h
View file @
c282da7d
...
...
@@ -364,6 +364,8 @@ public:
Document
::
Ptr
documentFromSource
(
const
QByteArray
&
preprocessedCode
,
const
QString
&
fileName
)
const
;
Symbol
*
findMatchingDefinition
(
Symbol
*
symbol
)
const
;
private:
void
simplified_helper
(
Document
::
Ptr
doc
,
Snapshot
*
snapshot
)
const
;
...
...
src/libs/cplusplus/LookupContext.cpp
View file @
c282da7d
...
...
@@ -46,12 +46,12 @@
using
namespace
CPlusPlus
;
static
void
fullyQualifiedName
(
Symbol
*
symbol
,
QList
<
const
Name
*>
*
names
)
static
void
fullyQualifiedName
_helper
(
Symbol
*
symbol
,
QList
<
const
Name
*>
*
names
)
{
if
(
!
symbol
)
return
;
fullyQualifiedName
(
symbol
->
enclosingSymbol
(),
names
);
fullyQualifiedName
_helper
(
symbol
->
enclosingSymbol
(),
names
);
if
(
symbol
->
name
()
&&
(
symbol
->
isClass
()
||
symbol
->
isNamespace
()))
{
if
(
const
QualifiedNameId
*
q
=
symbol
->
name
()
->
asQualifiedNameId
())
{
...
...
@@ -119,6 +119,13 @@ LookupContext &LookupContext::operator = (const LookupContext &other)
return
*
this
;
}
QList
<
const
Name
*>
LookupContext
::
fullyQualifiedName
(
Symbol
*
symbol
)
{
QList
<
const
Name
*>
names
;
fullyQualifiedName_helper
(
symbol
,
&
names
);
return
names
;
}
QSharedPointer
<
CreateBindings
>
LookupContext
::
bindings
()
const
{
if
(
!
_bindings
)
...
...
@@ -230,8 +237,7 @@ QList<Symbol *> LookupContext::lookup(const Name *name, Scope *scope) const
if
(
fun
->
name
()
&&
fun
->
name
()
->
isQualifiedNameId
())
{
const
QualifiedNameId
*
q
=
fun
->
name
()
->
asQualifiedNameId
();
QList
<
const
Name
*>
path
;
fullyQualifiedName
(
scope
->
owner
(),
&
path
);
QList
<
const
Name
*>
path
=
fullyQualifiedName
(
scope
->
owner
());
for
(
unsigned
index
=
0
;
index
<
q
->
nameCount
()
-
1
;
++
index
)
{
// ### TODO remove me.
const
Name
*
name
=
q
->
nameAt
(
index
);
...
...
@@ -681,8 +687,7 @@ ClassOrNamespace *CreateBindings::globalNamespace() const
ClassOrNamespace
*
CreateBindings
::
findClassOrNamespace
(
Symbol
*
symbol
)
{
QList
<
const
Name
*>
names
;
fullyQualifiedName
(
symbol
,
&
names
);
const
QList
<
const
Name
*>
names
=
LookupContext
::
fullyQualifiedName
(
symbol
);
if
(
names
.
isEmpty
())
return
_globalNamespace
;
...
...
src/libs/cplusplus/LookupContext.h
View file @
c282da7d
...
...
@@ -231,6 +231,8 @@ public:
Control
*
control
()
const
;
// ### deprecate
static
QList
<
const
Name
*>
fullyQualifiedName
(
Symbol
*
symbol
);
private:
Control
*
_control
;
...
...
src/plugins/cppeditor/cppeditor.cpp
View file @
c282da7d
...
...
@@ -1271,7 +1271,7 @@ void CPPEditor::switchDeclarationDefinition()
if
(
declaration
)
openCppEditorAt
(
linkToSymbol
(
declaration
));
}
else
if
(
lastSymbol
->
type
()
->
isFunctionType
())
{
if
(
Symbol
*
def
=
findDefinition
(
lastSymbol
))
if
(
Symbol
*
def
=
findDefinition
(
lastSymbol
,
snapshot
))
openCppEditorAt
(
linkToSymbol
(
def
));
}
}
...
...
@@ -1444,7 +1444,7 @@ CPPEditor::Link CPPEditor::findLinkAt(const QTextCursor &cursor,
if
(
Symbol
*
symbol
=
result
.
lastVisibleSymbol
())
{
Symbol
*
def
=
0
;
if
(
resolveTarget
&&
!
lastSymbol
->
isFunction
())
def
=
findDefinition
(
symbol
);
def
=
findDefinition
(
symbol
,
snapshot
);
link
=
linkToSymbol
(
def
?
def
:
symbol
);
link
.
begin
=
beginOfToken
;
...
...
@@ -1482,91 +1482,15 @@ void CPPEditor::jumpToDefinition()
openLink
(
findLinkAt
(
textCursor
()));
}
Symbol
*
CPPEditor
::
findDefinition
(
Symbol
*
symbol
)
Symbol
*
CPPEditor
::
findDefinition
(
Symbol
*
symbol
,
const
Snapshot
&
snapshot
)
{
if
(
symbol
->
isFunction
())
return
0
;
// symbol is a function definition.
Function
*
funTy
=
symbol
->
type
()
->
asFunctionType
();
if
(
!
funTy
)
return
0
;
// symbol does not have function type.
else
if
(
!
symbol
->
type
()
->
isFunctionType
())
return
0
;
// not a function declaration
const
Name
*
name
=
symbol
->
name
();
if
(
!
name
)
return
0
;
// skip anonymous functions!
if
(
const
QualifiedNameId
*
q
=
name
->
asQualifiedNameId
())
name
=
q
->
unqualifiedNameId
();
// map from file names to function definitions.
QMap
<
QString
,
QList
<
Function
*>
>
functionDefinitions
;
// find function definitions.
FindFunctionDefinitions
findFunctionDefinitions
;
// save the current snapshot
const
Snapshot
snapshot
=
m_modelManager
->
snapshot
();
foreach
(
Document
::
Ptr
doc
,
snapshot
)
{
if
(
Scope
*
globals
=
doc
->
globalSymbols
())
{
QList
<
Function
*>
*
localFunctionDefinitions
=
&
functionDefinitions
[
doc
->
fileName
()];
findFunctionDefinitions
(
name
,
globals
,
localFunctionDefinitions
);
}
}
// a dummy document.
Document
::
Ptr
expressionDocument
=
Document
::
create
(
"<empty>"
);
Function
*
bestMatch
=
0
;
int
bestScore
=
-
1
;
QMapIterator
<
QString
,
QList
<
Function
*>
>
it
(
functionDefinitions
);
while
(
it
.
hasNext
())
{
it
.
next
();
// get the instance of the document.
Document
::
Ptr
thisDocument
=
snapshot
.
document
(
it
.
key
());
foreach
(
Function
*
f
,
it
.
value
())
{
int
score
=
0
;
// current function's score
const
int
funTyArgsCount
=
funTy
->
argumentCount
();
const
int
fArgsCount
=
f
->
argumentCount
();
// max score if arguments count equals
if
(
funTyArgsCount
==
fArgsCount
)
score
+=
funTyArgsCount
+
1
;
else
score
+=
(
funTyArgsCount
<
fArgsCount
)
?
funTyArgsCount
:
fArgsCount
;
// +1 to score for every equal parameter
unsigned
minCount
=
(
funTyArgsCount
<
fArgsCount
)
?
funTyArgsCount
:
fArgsCount
;
for
(
unsigned
i
=
0
;
i
<
minCount
;
++
i
)
if
(
Symbol
*
funTyArg
=
funTy
->
argumentAt
(
i
))
if
(
Symbol
*
fArg
=
f
->
argumentAt
(
i
))
if
(
funTyArg
->
type
().
isEqualTo
(
fArg
->
type
()))
score
++
;
if
(
score
>
bestScore
)
{
// create a lookup context
const
DeprecatedLookupContext
context
(
f
,
expressionDocument
,
thisDocument
,
snapshot
);
// search the matching definition for the function declaration `symbol'.
foreach
(
Symbol
*
s
,
context
.
resolve
(
f
->
name
()))
{
if
(
s
==
symbol
)
{
bestMatch
=
f
;
bestScore
=
score
;
}
}
}
}
}
return
bestMatch
;
return
snapshot
.
findMatchingDefinition
(
symbol
);
}
unsigned
CPPEditor
::
editorRevision
()
const
...
...
src/plugins/cppeditor/cppeditor.h
View file @
c282da7d
...
...
@@ -252,7 +252,7 @@ private:
CPlusPlus
::
Symbol
*
markSymbols
();
bool
sortedMethodOverview
()
const
;
CPlusPlus
::
Symbol
*
findDefinition
(
CPlusPlus
::
Symbol
*
symbol
);
CPlusPlus
::
Symbol
*
findDefinition
(
CPlusPlus
::
Symbol
*
symbol
,
const
CPlusPlus
::
Snapshot
&
snapshot
);
virtual
void
indentBlock
(
QTextDocument
*
doc
,
QTextBlock
block
,
QChar
typedChar
);
TextEditor
::
ITextEditor
*
openCppEditorAt
(
const
QString
&
fileName
,
int
line
,
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a 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