Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
What's new
10
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Open sidebar
Marco Bubke
flatpak-qt-creator
Commits
8dd13fde
Commit
8dd13fde
authored
Sep 21, 2009
by
Erik Verbruggen
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Rewrote and improved navigation.
parent
b92e1a0a
Changes
8
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
367 additions
and
180 deletions
+367
-180
src/plugins/duieditor/duidocument.cpp
src/plugins/duieditor/duidocument.cpp
+62
-2
src/plugins/duieditor/duidocument.h
src/plugins/duieditor/duidocument.h
+16
-3
src/plugins/duieditor/duieditor.cpp
src/plugins/duieditor/duieditor.cpp
+3
-4
src/plugins/duieditor/duimodelmanager.cpp
src/plugins/duieditor/duimodelmanager.cpp
+22
-20
src/plugins/duieditor/idcollector.cpp
src/plugins/duieditor/idcollector.cpp
+27
-5
src/plugins/duieditor/idcollector.h
src/plugins/duieditor/idcollector.h
+10
-2
src/plugins/duieditor/navigationtokenfinder.cpp
src/plugins/duieditor/navigationtokenfinder.cpp
+210
-135
src/plugins/duieditor/navigationtokenfinder.h
src/plugins/duieditor/navigationtokenfinder.h
+17
-9
No files found.
src/plugins/duieditor/duidocument.cpp
View file @
8dd13fde
...
...
@@ -27,6 +27,7 @@
**
**************************************************************************/
#include "idcollector.h"
#include "duidocument.h"
#include "qmljsast_p.h"
#include "qmljslexer_p.h"
...
...
@@ -44,12 +45,21 @@ DuiDocument::DuiDocument(const QString &fileName)
,
_fileName
(
fileName
)
,
_parsedCorrectly
(
false
)
{
const
int
slashIdx
=
fileName
.
lastIndexOf
(
'/'
);
if
(
slashIdx
!=
-
1
)
_path
=
fileName
.
left
(
slashIdx
);
if
(
fileName
.
toLower
().
endsWith
(
".qml"
))
_componentName
=
fileName
.
mid
(
slashIdx
+
1
,
fileName
.
size
()
-
(
slashIdx
+
1
)
-
4
);
}
DuiDocument
::~
DuiDocument
()
{
delete
_engine
;
delete
_pool
;
if
(
_engine
)
delete
_engine
;
if
(
_pool
)
delete
_pool
;
}
DuiDocument
::
Ptr
DuiDocument
::
create
(
const
QString
&
fileName
)
...
...
@@ -81,6 +91,7 @@ bool DuiDocument::parse()
_engine
=
new
Engine
();
_pool
=
new
NodePool
(
_fileName
,
_engine
);
_ids
.
clear
();
Lexer
lexer
(
_engine
);
Parser
parser
(
_engine
);
...
...
@@ -90,6 +101,12 @@ bool DuiDocument::parse()
_parsedCorrectly
=
parser
.
parse
();
_program
=
parser
.
ast
();
_diagnosticMessages
=
parser
.
diagnosticMessages
();
if
(
_parsedCorrectly
&&
_program
)
{
Internal
::
IdCollector
collect
;
_ids
=
collect
(
_program
);
}
return
_parsedCorrectly
;
}
...
...
@@ -100,3 +117,46 @@ Snapshot::Snapshot()
Snapshot
::~
Snapshot
()
{
}
void
Snapshot
::
insert
(
const
DuiDocument
::
Ptr
&
document
)
{
QMap
<
QString
,
DuiDocument
::
Ptr
>::
insert
(
document
->
fileName
(),
document
);
}
DuiDocument
::
PtrList
Snapshot
::
importedDocuments
(
const
DuiDocument
::
Ptr
&
doc
,
const
QString
&
importPath
)
{
DuiDocument
::
PtrList
result
;
const
QString
docPath
=
doc
->
path
()
+
'/'
+
importPath
;
for
(
Iterator
i
=
iterator
();
i
.
hasNext
();)
{
DuiDocument
::
Ptr
candidate
=
i
.
next
().
value
();
if
(
candidate
==
doc
)
continue
;
if
(
candidate
->
path
()
==
doc
->
path
()
||
candidate
->
path
()
==
docPath
)
result
.
append
(
candidate
);
}
return
result
;
}
QMap
<
QString
,
DuiDocument
::
Ptr
>
Snapshot
::
componentsDefinedByImportedDocuments
(
const
DuiDocument
::
Ptr
&
doc
,
const
QString
&
importPath
)
{
QMap
<
QString
,
DuiDocument
::
Ptr
>
result
;
const
QString
docPath
=
doc
->
path
()
+
'/'
+
importPath
;
for
(
Iterator
i
=
iterator
();
i
.
hasNext
();)
{
DuiDocument
::
Ptr
candidate
=
i
.
next
().
value
();
if
(
candidate
==
doc
)
continue
;
if
(
candidate
->
path
()
==
doc
->
path
()
||
candidate
->
path
()
==
docPath
)
result
.
insert
(
candidate
->
componentName
(),
candidate
);
}
return
result
;
}
src/plugins/duieditor/duidocument.h
View file @
8dd13fde
...
...
@@ -29,8 +29,10 @@
#ifndef DUIDOCUMENT_H
#define DUIDOCUMENT_H
#include <QtCore/Q
SharedPointer
>
#include <QtCore/Q
List
>
#include <QtCore/QMap>
#include <QtCore/QPair>
#include <QtCore/QSharedPointer>
#include <QtCore/QString>
#include "duieditor_global.h"
...
...
@@ -44,6 +46,8 @@ class DUIEDITOR_EXPORT DuiDocument
{
public:
typedef
QSharedPointer
<
DuiDocument
>
Ptr
;
typedef
QList
<
DuiDocument
::
Ptr
>
PtrList
;
typedef
QMap
<
QString
,
QPair
<
QmlJS
::
AST
::
SourceLocation
,
QmlJS
::
AST
::
Node
*>
>
IdTable
;
protected:
DuiDocument
(
const
QString
&
fileName
);
...
...
@@ -62,7 +66,11 @@ public:
bool
isParsedCorrectly
()
const
{
return
_parsedCorrectly
;
}
IdTable
ids
()
const
{
return
_ids
;
}
QString
fileName
()
const
{
return
_fileName
;
}
QString
path
()
const
{
return
_path
;
}
QString
componentName
()
const
{
return
_componentName
;
}
private:
QmlJS
::
Engine
*
_engine
;
...
...
@@ -70,8 +78,11 @@ private:
QmlJS
::
AST
::
UiProgram
*
_program
;
QList
<
QmlJS
::
DiagnosticMessage
>
_diagnosticMessages
;
QString
_fileName
;
QString
_path
;
QString
_componentName
;
QString
_source
;
bool
_parsedCorrectly
;
IdTable
_ids
;
};
class
DUIEDITOR_EXPORT
Snapshot
:
protected
QMap
<
QString
,
DuiDocument
::
Ptr
>
...
...
@@ -80,8 +91,7 @@ public:
Snapshot
();
~
Snapshot
();
void
insert
(
const
DuiDocument
::
Ptr
&
document
)
{
QMap
<
QString
,
DuiDocument
::
Ptr
>::
insert
(
document
->
fileName
(),
document
);
}
void
insert
(
const
DuiDocument
::
Ptr
&
document
);
typedef
QMapIterator
<
QString
,
DuiDocument
::
Ptr
>
Iterator
;
Iterator
iterator
()
const
...
...
@@ -89,6 +99,9 @@ public:
DuiDocument
::
Ptr
document
(
const
QString
&
fileName
)
const
{
return
value
(
fileName
);
}
DuiDocument
::
PtrList
importedDocuments
(
const
DuiDocument
::
Ptr
&
doc
,
const
QString
&
importPath
);
QMap
<
QString
,
DuiDocument
::
Ptr
>
componentsDefinedByImportedDocuments
(
const
DuiDocument
::
Ptr
&
doc
,
const
QString
&
importPath
);
};
}
// emd of namespace DuiEditor
...
...
src/plugins/duieditor/duieditor.cpp
View file @
8dd13fde
...
...
@@ -714,11 +714,10 @@ TextEditor::BaseTextEditor::Link ScriptEditor::findLinkAt(const QTextCursor &cur
if
(
!
doc
)
return
link
;
QMap
<
QString
,
QmlJS
::
AST
::
SourceLocation
>
idPositions
=
IdCollector
()(
doc
->
program
());
NavigationTokenFinder
finder
;
if
(
finder
(
doc
->
program
(),
cursor
.
position
(),
resolveTarget
,
idPositions
))
{
link
.
fileName
=
file
()
->
fileName
();
finder
(
doc
,
cursor
.
position
(),
snapshot
);
if
(
finder
.
targetFound
())
{
link
.
fileName
=
finder
.
fileName
();
link
.
pos
=
finder
.
linkPosition
();
link
.
length
=
finder
.
linkLength
();
...
...
src/plugins/duieditor/duimodelmanager.cpp
View file @
8dd13fde
...
...
@@ -69,34 +69,36 @@ void DuiModelManager::updateSourceFiles(const QStringList &files)
QFuture
<
void
>
DuiModelManager
::
refreshSourceFiles
(
const
QStringList
&
sourceFiles
)
{
if
(
!
sourceFiles
.
isEmpty
())
{
const
QMap
<
QString
,
QString
>
workingCopy
=
buildWorkingCopyList
();
if
(
sourceFiles
.
isEmpty
())
{
return
QFuture
<
void
>
();
}
QFuture
<
void
>
result
=
QtConcurrent
::
run
(
&
DuiModelManager
::
parse
,
workingCopy
,
sourceFiles
,
this
);
const
QMap
<
QString
,
QString
>
workingCopy
=
buildWorkingCopyList
();
if
(
m_synchronizer
.
futures
().
size
()
>
10
)
{
QList
<
QFuture
<
void
>
>
futures
=
m_synchronizer
.
futures
();
QFuture
<
void
>
result
=
QtConcurrent
::
run
(
&
DuiModelManager
::
parse
,
workingCopy
,
sourceFiles
,
this
);
m_synchronizer
.
clearFutures
();
if
(
m_synchronizer
.
futures
().
size
()
>
10
)
{
QList
<
QFuture
<
void
>
>
futures
=
m_synchronizer
.
futures
();
foreach
(
QFuture
<
void
>
future
,
futures
)
{
if
(
!
(
future
.
isFinished
()
||
future
.
isCanceled
()))
m_synchronizer
.
addFuture
(
future
);
}
m_synchronizer
.
clearFutures
();
foreach
(
QFuture
<
void
>
future
,
futures
)
{
if
(
!
(
future
.
isFinished
()
||
future
.
isCanceled
()))
m_synchronizer
.
addFuture
(
future
);
}
}
m_synchronizer
.
addFuture
(
result
);
m_synchronizer
.
addFuture
(
result
);
if
(
sourceFiles
.
count
()
>
1
)
{
m_core
->
progressManager
()
->
addTask
(
result
,
tr
(
"Indexing"
),
DuiEditor
::
Constants
::
TASK_INDEX
,
Core
::
ProgressManager
::
CloseOnSuccess
);
}
return
result
;
if
(
sourceFiles
.
count
()
>
1
)
{
m_core
->
progressManager
()
->
addTask
(
result
,
tr
(
"Indexing"
),
DuiEditor
::
Constants
::
TASK_INDEX
,
Core
::
ProgressManager
::
CloseOnSuccess
);
}
return
QFuture
<
void
>
();
return
result
;
}
QMap
<
QString
,
QString
>
DuiModelManager
::
buildWorkingCopyList
()
...
...
src/plugins/duieditor/idcollector.cpp
View file @
8dd13fde
...
...
@@ -6,13 +6,35 @@ using namespace QmlJS;
using
namespace
QmlJS
::
AST
;
using
namespace
DuiEditor
::
Internal
;
QMap
<
QString
,
QmlJS
::
AST
::
SourceLocation
>
IdCollector
::
operator
()(
QmlJS
::
AST
::
UiProgram
*
ast
)
QMap
<
QString
,
QPair
<
QmlJS
::
AST
::
SourceLocation
,
QmlJS
::
AST
::
Node
*>
>
IdCollector
::
operator
()(
QmlJS
::
AST
::
UiProgram
*
ast
)
{
_id
Location
s
.
clear
();
_ids
.
clear
();
Node
::
accept
(
ast
,
this
);
return
_idLocations
;
return
_ids
;
}
bool
IdCollector
::
visit
(
QmlJS
::
AST
::
UiObjectBinding
*
ast
)
{
_scopes
.
push
(
ast
);
return
true
;
}
bool
IdCollector
::
visit
(
QmlJS
::
AST
::
UiObjectDefinition
*
ast
)
{
_scopes
.
push
(
ast
);
return
true
;
}
void
IdCollector
::
endVisit
(
QmlJS
::
AST
::
UiObjectBinding
*
)
{
_scopes
.
pop
();
}
void
IdCollector
::
endVisit
(
QmlJS
::
AST
::
UiObjectDefinition
*
)
{
_scopes
.
pop
();
}
bool
IdCollector
::
visit
(
QmlJS
::
AST
::
UiScriptBinding
*
ast
)
...
...
@@ -29,6 +51,6 @@ void IdCollector::addId(QmlJS::NameId* id, const QmlJS::AST::SourceLocation &idL
{
const
QString
idString
=
id
->
asString
();
if
(
!
_id
Location
s
.
contains
(
idString
))
_id
Location
s
[
idString
]
=
idLocation
;
if
(
!
_ids
.
contains
(
idString
))
_ids
[
idString
]
=
qMakePair
(
idLocation
,
_scopes
.
top
())
;
}
src/plugins/duieditor/idcollector.h
View file @
8dd13fde
...
...
@@ -2,6 +2,8 @@
#define IDCOLLECTOR_H
#include <QMap>
#include <QPair>
#include <QStack>
#include <QString>
#include "qmljsastvisitor_p.h"
...
...
@@ -14,16 +16,22 @@ namespace Internal {
class
IdCollector
:
protected
QmlJS
::
AST
::
Visitor
{
public:
QMap
<
QString
,
QmlJS
::
AST
::
SourceLocation
>
operator
()(
QmlJS
::
AST
::
UiProgram
*
ast
);
QMap
<
QString
,
QPair
<
QmlJS
::
AST
::
SourceLocation
,
QmlJS
::
AST
::
Node
*>
>
operator
()(
QmlJS
::
AST
::
UiProgram
*
ast
);
protected:
virtual
bool
visit
(
QmlJS
::
AST
::
UiObjectBinding
*
ast
);
virtual
bool
visit
(
QmlJS
::
AST
::
UiObjectDefinition
*
ast
);
virtual
bool
visit
(
QmlJS
::
AST
::
UiScriptBinding
*
ast
);
virtual
void
endVisit
(
QmlJS
::
AST
::
UiObjectBinding
*
);
virtual
void
endVisit
(
QmlJS
::
AST
::
UiObjectDefinition
*
);
private:
void
addId
(
QmlJS
::
NameId
*
id
,
const
QmlJS
::
AST
::
SourceLocation
&
idLocation
);
private:
QMap
<
QString
,
QmlJS
::
AST
::
SourceLocation
>
_idLocations
;
QMap
<
QString
,
QPair
<
QmlJS
::
AST
::
SourceLocation
,
QmlJS
::
AST
::
Node
*>
>
_ids
;
QStack
<
QmlJS
::
AST
::
Node
*>
_scopes
;
};
}
// namespace Internal
...
...
src/plugins/duieditor/navigationtokenfinder.cpp
View file @
8dd13fde
...
...
@@ -5,23 +5,60 @@
using
namespace
QmlJS
;
using
namespace
QmlJS
::
AST
;
using
namespace
DuiEditor
;
using
namespace
DuiEditor
::
Internal
;
bool
NavigationTokenFinder
::
operator
()(
QmlJS
::
AST
::
UiProgram
*
ast
,
int
position
,
bool
resolveTarget
,
const
QMap
<
QString
,
QmlJS
::
AST
::
SourceLocation
>
&
idPositions
)
void
NavigationTokenFinder
::
operator
()(
const
DuiDocument
::
Ptr
&
doc
,
int
position
,
const
Snapshot
&
snapshot
)
{
_resolveTarget
=
resolveTarget
;
_doc
=
doc
;
_snapshot
=
snapshot
;
_pos
=
position
;
_idPositions
=
idPositions
;
_scopes
.
clear
();
_linkPosition
=
-
1
;
_fileName
.
clear
();
_targetLine
=
-
1
;
Node
::
accept
(
ast
,
this
);
Node
::
accept
(
doc
->
program
(),
this
);
}
static
QStringList
buildQualifiedId
(
QmlJS
::
AST
::
FieldMemberExpression
*
expr
)
{
QStringList
qId
;
if
(
FieldMemberExpression
*
baseExpr
=
cast
<
FieldMemberExpression
*>
(
expr
->
base
))
{
qId
=
buildQualifiedId
(
baseExpr
);
}
else
if
(
IdentifierExpression
*
idExpr
=
cast
<
IdentifierExpression
*>
(
expr
->
base
))
{
qId
.
append
(
idExpr
->
name
->
asString
());
}
else
{
return
qId
;
}
if
(
resolveTarget
)
return
targetFound
();
else
return
linkFound
();
qId
.
append
(
expr
->
name
->
asString
());
return
qId
;
}
bool
NavigationTokenFinder
::
visit
(
QmlJS
::
AST
::
FieldMemberExpression
*
ast
)
{
if
(
linkFound
())
return
false
;
if
(
ast
->
firstSourceLocation
().
offset
<=
_pos
&&
_pos
<=
ast
->
lastSourceLocation
().
end
())
{
if
(
ast
->
identifierToken
.
offset
<=
_pos
&&
_pos
<=
ast
->
identifierToken
.
end
())
{
// found it:
_linkPosition
=
ast
->
identifierToken
.
offset
;
_linkLength
=
ast
->
identifierToken
.
end
()
-
_linkPosition
;
const
QStringList
qualifiedId
(
buildQualifiedId
(
ast
));
if
(
!
qualifiedId
.
isEmpty
())
findDeclaration
(
qualifiedId
);
}
else
{
Node
::
accept
(
ast
->
base
,
this
);
}
return
false
;
}
return
true
;
}
bool
NavigationTokenFinder
::
visit
(
QmlJS
::
AST
::
IdentifierExpression
*
ast
)
...
...
@@ -33,8 +70,7 @@ bool NavigationTokenFinder::visit(QmlJS::AST::IdentifierExpression *ast)
_linkPosition
=
ast
->
identifierToken
.
offset
;
_linkLength
=
ast
->
identifierToken
.
length
;
if
(
Node
*
node
=
findDeclarationInScopesOrIds
(
ast
->
name
))
rememberStartPosition
(
node
);
findDeclaration
(
QStringList
()
<<
ast
->
name
->
asString
());
}
return
false
;
...
...
@@ -50,6 +86,11 @@ bool NavigationTokenFinder::visit(QmlJS::AST::UiArrayBinding *ast)
return
false
;
}
bool
NavigationTokenFinder
::
visit
(
QmlJS
::
AST
::
UiImportList
*
)
{
return
false
;
}
bool
NavigationTokenFinder
::
visit
(
QmlJS
::
AST
::
UiPublicMember
*
ast
)
{
if
(
linkFound
())
...
...
@@ -64,10 +105,7 @@ bool NavigationTokenFinder::visit(QmlJS::AST::Block *ast)
{
_scopes
.
push
(
ast
);
if
(
linkFound
())
return
false
;
return
true
;
return
!
linkFound
();
}
void
NavigationTokenFinder
::
endVisit
(
QmlJS
::
AST
::
Block
*
)
...
...
@@ -79,11 +117,10 @@ bool NavigationTokenFinder::visit(QmlJS::AST::UiObjectBinding *ast)
{
_scopes
.
push
(
ast
);
if
(
linkFound
())
return
false
;
Node
::
accept
(
ast
->
qualifiedTypeNameId
,
this
);
Node
::
accept
(
ast
->
initializer
,
this
);
if
(
!
linkFound
())
{
checkType
(
ast
->
qualifiedTypeNameId
);
Node
::
accept
(
ast
->
initializer
,
this
);
}
return
false
;
}
...
...
@@ -97,10 +134,12 @@ bool NavigationTokenFinder::visit(QmlJS::AST::UiObjectDefinition *ast)
{
_scopes
.
push
(
ast
);
if
(
linkFound
())
return
false
;
if
(
!
linkFound
())
{
checkType
(
ast
->
qualifiedTypeNameId
);
Node
::
accept
(
ast
->
initializer
,
this
);
}
return
tru
e
;
return
fals
e
;
}
void
NavigationTokenFinder
::
endVisit
(
QmlJS
::
AST
::
UiObjectDefinition
*
)
...
...
@@ -108,36 +147,34 @@ void NavigationTokenFinder::endVisit(QmlJS::AST::UiObjectDefinition *)
_scopes
.
pop
();
}
bool
NavigationTokenFinder
::
visit
(
QmlJS
::
AST
::
UiQualifiedId
*
ast
)
void
NavigationTokenFinder
::
checkType
(
QmlJS
::
AST
::
UiQualifiedId
*
ast
)
{
if
(
linkFound
())
return
false
;
if
(
ast
->
identifierToken
.
offset
<=
_pos
)
{
for
(
UiQualifiedId
*
iter
=
ast
;
iter
;
iter
=
iter
->
next
)
{
if
(
_pos
<=
iter
->
identifierToken
.
end
())
{
_linkPosition
=
ast
->
identifierToken
.
offset
;
for
(
UiQualifiedId
*
iter2
=
ast
;
iter2
;
iter2
=
iter2
->
next
)
QStringList
names
;
for
(
UiQualifiedId
*
iter2
=
ast
;
iter2
;
iter2
=
iter2
->
next
)
{
_linkLength
=
iter2
->
identifierToken
.
end
()
-
_linkPosition
;
names
.
append
(
iter2
->
name
->
asString
());
}
findTypeDeclaration
(
names
);
if
(
Node
*
node
=
findDeclarationInScopesOrIds
(
ast
))
rememberStartPosition
(
node
);
return
false
;
return
;
}
}
}
return
false
;
}
bool
NavigationTokenFinder
::
visit
(
QmlJS
::
AST
::
UiScriptBinding
*
ast
)
{
if
(
linkFound
())
return
false
;
Node
::
accept
(
ast
->
statement
,
this
);
if
(
!
linkFound
())
{
if
(
ast
->
qualifiedId
&&
!
ast
->
qualifiedId
->
next
&&
ast
->
qualifiedId
->
name
&&
ast
->
qualifiedId
->
name
->
asString
()
==
"id"
)
return
false
;
else
Node
::
accept
(
ast
->
statement
,
this
);
}
return
false
;
}
...
...
@@ -147,134 +184,172 @@ bool NavigationTokenFinder::visit(QmlJS::AST::UiSourceElement * /*ast*/)
return
false
;
}
void
NavigationTokenFinder
::
rememberStartPosition
(
QmlJS
::
AST
::
Node
*
node
)
bool
NavigationTokenFinder
::
findInJS
(
const
QStringList
&
qualifiedId
,
QmlJS
::
AST
::
Block
*
block
)
{
if
(
UiObjectMember
*
om
=
dynamic_cast
<
UiObjectMember
*>
(
node
))
{
_targetLine
=
om
->
firstSourceLocation
().
startLine
;
_targetColumn
=
om
->
firstSourceLocation
().
startColumn
;
}
else
if
(
VariableDeclaration
*
vd
=
cast
<
VariableDeclaration
*>
(
node
))
{
_targetLine
=
vd
->
identifierToken
.
startLine
;
_targetColumn
=
vd
->
identifierToken
.
startColumn
;
}
else
{
// qWarning() << "Found declaration of unknown type as a navigation target";
}
}
if
(
qualifiedId
.
size
()
>
1
)
return
false
;
// we can only find "simple" JavaScript variables this way
void
NavigationTokenFinder
::
rememberStartPosition
(
const
QmlJS
::
AST
::
SourceLocation
&
location
)
{
_targetLine
=
location
.
startLine
;
_targetColumn
=
location
.
startColumn
;
}
const
QString
id
=
qualifiedId
[
0
];
static
QmlJS
::
AST
::
Node
*
findDeclaration
(
const
QString
&
nameId
,
QmlJS
::
AST
::
UiObjectMember
*
m
)
{
if
(
UiPublicMember
*
p
=
cast
<
UiPublicMember
*>
(
m
))
{
if
(
p
->
name
->
asString
()
==
nameId
)
return
p
;
}
else
if
(
UiObjectBinding
*
o
=
cast
<
UiObjectBinding
*>
(
m
)
)
{
if
(
!
(
o
->
qualifiedId
->
next
)
&&
o
->
qualifiedId
->
name
->
asString
()
==
nameId
)
return
o
;
}
else
if
(
UiArrayBinding
*
a
=
cast
<
UiArrayBinding
*>
(
m
))
{
if
(
!
(
a
->
qualifiedId
->
next
)
&&
a
->
qualifiedId
->
name
->
asString
()
==
nameId
)
return
a
;
for
(
StatementList
*
iter
=
block
->
statements
;
iter
;
iter
=
iter
->
next
)
{
Statement
*
stmt
=
iter
->
statement
;
if
(
VariableStatement
*
varStmt
=
cast
<
VariableStatement
*>
(
stmt
))
{
for
(
VariableDeclarationList
*
varIter
=
varStmt
->
declarations
;
varIter
;
varIter
=
varIter
->
next
)
{
if
(
varIter
->
declaration
&&
varIter
->
declaration
->
name
&&
varIter
->
declaration
->
name
->
asString
()
==
id
)
{
rememberLocation
(
varIter
->
declaration
->
identifierToken
);
return
true
;
}
}
}
}
return
0
;
return
false
;
}
static
QmlJS
::
AST
::
Node
*
findDeclaration
(
const
QString
&
nameId
,
QmlJS
::
AST
::
UiObjectMemberList
*
l
)
static
bool
matches
(
UiQualifiedId
*
candidate
,
const
QStringList
&
wanted
)
{
for
(
UiObjectMemberList
*
iter
=
l
;
iter
;
iter
=
iter
->
next
)
if
(
Node
*
n
=
findDeclaration
(
nameId
,
iter
->
member
))
return
n
;
UiQualifiedId
*
iter
=
candidate
;
for
(
int
i
=
0
;
i
<
wanted
.
size
();
++
i
)
{
if
(
!
iter
)
return
false
;
if
(
iter
->
name
->
asString
()
!=
wanted
[
i
])
return
false
;
iter
=
iter
->
next
;
}
return
0
;
return
!
iter
;
}
static
QmlJS
::
AST
::
Node
*
findDeclaration
(
const
QString
&
nameId
,
QmlJS
::
AST
::
Statement
*
s
)
bool
NavigationTokenFinder
::
findProperty
(
const
QStringList
&
qualifiedId
,
QmlJS
::
AST
::
UiQualifiedId
*
typeId
,
QmlJS
::
AST
::
UiObjectMemberList
*
ast
,
int
scopeLevel
)
{
if
(
VariableStatement
*
v
=
cast
<
VariableStatement
*>
(
s
))
{
for
(
VariableDeclarationList
*
l
=
v
->
declarations
;
l
;
l
=
l
->
next
)
{
if
(
l
->
declaration
->
name
->
asString
()
==
nameId
)
return
l
->
declaration
;
// 1. try the "overridden" properties:
for
(
UiObjectMemberList
*
iter
=
ast
;
iter
;
iter
=
iter
->
next
)
{
UiObjectMember
*
member
=
iter
->
member
;
if
(
UiPublicMember
*
publicMember
=
cast
<
UiPublicMember
*>
(
member
))
{
if
(
publicMember
->
name
&&
qualifiedId
.
size
()
==
1
&&
publicMember
->
name
->
asString
()
==
qualifiedId
.
first
())
{
rememberLocation
(
publicMember
->
identifierToken
);
return
true
;
}
}
e