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
Tobias Hunger
qt-creator
Commits
71549ec6
Commit
71549ec6
authored
Sep 11, 2009
by
Erik Verbruggen
Browse files
First version of QML navigation.
parent
e58ff77b
Changes
14
Hide whitespace changes
Inline
Side-by-side
src/plugins/coreplugin/coreconstants.h
View file @
71549ec6
...
...
@@ -180,6 +180,7 @@ const char * const G_EDIT_OTHER = "QtCreator.Group.Edit.Other";
// advanced edit menu groups
const
char
*
const
G_EDIT_FORMAT
=
"QtCreator.Group.Edit.Format"
;
const
char
*
const
G_EDIT_REFORMAT
=
"QtCreator.Group.Edit.Reformat"
;
const
char
*
const
G_EDIT_COLLAPSING
=
"QtCreator.Group.Edit.Collapsing"
;
const
char
*
const
G_EDIT_FONT
=
"QtCreator.Group.Edit.Font"
;
const
char
*
const
G_EDIT_EDITOR
=
"QtCreator.Group.Edit.Editor"
;
...
...
src/plugins/duieditor/duicodeformatter.cpp
0 → 100644
View file @
71549ec6
#include "duicodeformatter.h"
#include "qmljsast_p.h"
using
namespace
DuiEditor
::
Internal
;
using
namespace
QmlJS
;
using
namespace
QmlJS
::
AST
;
DuiCodeFormatter
::
DuiCodeFormatter
()
{
}
DuiCodeFormatter
::~
DuiCodeFormatter
()
{
}
bool
DuiCodeFormatter
::
visit
(
QmlJS
::
AST
::
UiProgram
*
ast
)
{
Node
::
accept
(
ast
->
imports
,
this
);
if
(
ast
->
imports
&&
ast
->
members
)
newline
();
Node
::
accept
(
ast
->
members
,
this
);
return
false
;
}
QString
DuiCodeFormatter
::
operator
()(
QmlJS
::
AST
::
UiProgram
*
ast
,
const
QString
&
originalSource
,
const
QList
<
QmlJS
::
AST
::
SourceLocation
>
&
comments
,
int
start
,
int
end
)
{
m_result
.
clear
();
m_result
.
reserve
(
originalSource
.
length
()
*
2
);
m_originalSource
=
originalSource
;
m_start
=
start
;
m_end
=
end
;
Node
::
acceptChild
(
ast
,
this
);
return
m_result
;
}
bool
DuiCodeFormatter
::
visit
(
UiImport
*
ast
)
{
append
(
"import "
);
append
(
ast
->
fileNameToken
);
if
(
ast
->
versionToken
.
isValid
())
{
append
(
' '
);
append
(
ast
->
versionToken
);
}
if
(
ast
->
asToken
.
isValid
())
{
append
(
" as "
);
append
(
ast
->
importIdToken
);
}
if
(
ast
->
semicolonToken
.
isValid
())
append
(
';'
);
newline
();
return
false
;
}
bool
DuiCodeFormatter
::
visit
(
UiObjectDefinition
*
ast
)
{
indent
();
Node
::
accept
(
ast
->
qualifiedTypeNameId
,
this
);
append
(
' '
);
Node
::
accept
(
ast
->
initializer
,
this
);
newline
();
return
false
;
}
bool
DuiCodeFormatter
::
visit
(
QmlJS
::
AST
::
UiQualifiedId
*
ast
)
{
for
(
UiQualifiedId
*
it
=
ast
;
it
;
it
=
it
->
next
)
{
append
(
it
->
name
->
asString
());
if
(
it
->
next
)
append
(
'.'
);
}
return
false
;
}
bool
DuiCodeFormatter
::
visit
(
QmlJS
::
AST
::
UiObjectInitializer
*
ast
)
{
append
(
ast
->
lbraceToken
.
offset
,
ast
->
rbraceToken
.
end
()
-
ast
->
lbraceToken
.
offset
);
return
false
;
}
src/plugins/duieditor/duicodeformatter.h
0 → 100644
View file @
71549ec6
#ifndef DUICODEFORMATTER_H
#define DUICODEFORMATTER_H
#include <QString>
#include "qmljsastfwd_p.h"
#include "qmljsastvisitor_p.h"
#include "qmljsengine_p.h"
namespace
DuiEditor
{
namespace
Internal
{
class
DuiCodeFormatter
:
protected
QmlJS
::
AST
::
Visitor
{
public:
DuiCodeFormatter
();
~
DuiCodeFormatter
();
QString
operator
()(
QmlJS
::
AST
::
UiProgram
*
ast
,
const
QString
&
originalSource
,
const
QList
<
QmlJS
::
AST
::
SourceLocation
>
&
comments
,
int
start
=
-
1
,
int
end
=
-
1
);
protected:
virtual
bool
visit
(
QmlJS
::
AST
::
UiProgram
*
ast
);
// virtual bool visit(UiImportList *ast);
virtual
bool
visit
(
QmlJS
::
AST
::
UiImport
*
ast
);
// virtual bool visit(UiPublicMember *ast);
// virtual bool visit(UiSourceElement *ast);
virtual
bool
visit
(
QmlJS
::
AST
::
UiObjectDefinition
*
ast
);
virtual
bool
visit
(
QmlJS
::
AST
::
UiObjectInitializer
*
ast
);
// virtual bool visit(UiObjectBinding *ast);
// virtual bool visit(UiScriptBinding *ast);
// virtual bool visit(UiArrayBinding *ast);
// virtual bool visit(UiObjectMemberList *ast);
// virtual bool visit(UiArrayMemberList *ast);
virtual
bool
visit
(
QmlJS
::
AST
::
UiQualifiedId
*
ast
);
// virtual bool visit(UiSignature *ast);
// virtual bool visit(UiFormalList *ast);
// virtual bool visit(UiFormal *ast);
//
// virtual void endVisit(UiProgram *ast);
// virtual void endVisit(UiImport *ast);
// virtual void endVisit(UiPublicMember *ast);
// virtual void endVisit(UiSourceElement *ast);
// virtual void endVisit(UiObjectDefinition *ast);
// virtual void endVisit(UiObjectInitializer *ast);
// virtual void endVisit(UiObjectBinding *ast);
// virtual void endVisit(UiScriptBinding *ast);
// virtual void endVisit(UiArrayBinding *ast);
// virtual void endVisit(UiObjectMemberList *ast);
// virtual void endVisit(UiArrayMemberList *ast);
// virtual void endVisit(UiQualifiedId *ast);
// virtual void endVisit(UiSignature *ast);
// virtual void endVisit(UiFormalList *ast);
// virtual void endVisit(UiFormal *ast);
private:
void
append
(
char
c
)
{
m_result
+=
c
;
}
void
append
(
char
*
s
)
{
m_result
+=
s
;
}
void
append
(
const
QString
&
s
)
{
m_result
+=
s
;
}
void
append
(
const
QmlJS
::
AST
::
SourceLocation
&
loc
)
{
m_result
+=
textAt
(
loc
);
}
void
append
(
int
pos
,
int
len
)
{
append
(
textAt
(
pos
,
len
));
}
QString
textAt
(
const
QmlJS
::
AST
::
SourceLocation
&
loc
)
const
{
return
textAt
(
loc
.
offset
,
loc
.
length
);
}
QString
textAt
(
int
pos
,
int
len
)
const
{
return
m_originalSource
.
mid
(
pos
,
len
);
}
void
indent
()
{
if
(
m_indentDepth
)
append
(
QString
(
' '
,
m_indentDepth
));
}
void
newline
()
{
append
(
'\n'
);
}
private:
QString
m_result
;
QString
m_originalSource
;
int
m_start
;
int
m_end
;
unsigned
m_indentDepth
;
};
}
// namespace Internal
}
// namespace DuiEditor
#endif // DUICODEFORMATTER_H
src/plugins/duieditor/duieditor.cpp
View file @
71549ec6
...
...
@@ -34,12 +34,14 @@
#include "duidocument.h"
#include "duimodelmanager.h"
#include "rewriter_p.h"
#include "qmljsastvisitor_p.h"
#include "qmljsast_p.h"
#include "qmljsengine_p.h"
#include "rewriter_p.h"
#include "navigationtokenfinder.h"
#include <coreplugin/icore.h>
#include <coreplugin/actionmanager/actionmanager.h>
#include <extensionsystem/pluginmanager.h>
...
...
@@ -67,7 +69,6 @@ enum {
using
namespace
QmlJS
;
using
namespace
QmlJS
::
AST
;
namespace
DuiEditor
{
namespace
Internal
{
...
...
@@ -702,6 +703,35 @@ void ScriptEditor::createToolBar(ScriptEditorEditable *editable)
toolBar
->
insertWidget
(
actions
.
first
(),
m_methodCombo
);
}
TextEditor
::
BaseTextEditor
::
Link
ScriptEditor
::
findLinkAt
(
const
QTextCursor
&
cursor
,
bool
resolveTarget
)
{
Link
link
;
if
(
!
m_modelManager
)
return
link
;
const
Snapshot
snapshot
=
m_modelManager
->
snapshot
();
DuiDocument
::
Ptr
doc
=
snapshot
.
document
(
file
()
->
fileName
());
if
(
!
doc
)
return
link
;
NavigationTokenFinder
finder
;
if
(
finder
(
doc
->
program
(),
cursor
.
position
(),
resolveTarget
))
{
link
.
fileName
=
file
()
->
fileName
();
link
.
pos
=
finder
.
linkPosition
();
link
.
length
=
finder
.
linkLength
();
link
.
line
=
finder
.
targetLine
();
link
.
column
=
finder
.
targetColumn
()
-
1
;
}
return
link
;
}
void
ScriptEditor
::
reformat
(
QTextDocument
*
,
QTextBlock
block
)
{
// TODO (EV)
}
void
ScriptEditor
::
contextMenuEvent
(
QContextMenuEvent
*
e
)
{
QMenu
*
menu
=
createStandardContextMenu
();
...
...
src/plugins/duieditor/duieditor.h
View file @
71549ec6
...
...
@@ -131,6 +131,8 @@ protected:
void
contextMenuEvent
(
QContextMenuEvent
*
e
);
TextEditor
::
BaseTextEditorEditable
*
createEditableInterface
();
void
createToolBar
(
ScriptEditorEditable
*
editable
);
TextEditor
::
BaseTextEditor
::
Link
findLinkAt
(
const
QTextCursor
&
cursor
,
bool
resolveTarget
=
true
);
virtual
void
reformat
(
QTextDocument
*
doc
,
QTextBlock
block
);
private:
virtual
bool
isElectricCharacter
(
const
QChar
&
ch
)
const
;
...
...
src/plugins/duieditor/duieditor.pro
View file @
71549ec6
...
...
@@ -19,7 +19,9 @@ HEADERS += duieditor.h \
duicompletionvisitor
.
h
\
duimodelmanagerinterface
.
h
\
duieditor_global
.
h
\
duimodelmanager
.
h
duimodelmanager
.
h
\
duicodeformatter
.
h
\
navigationtokenfinder
.
h
SOURCES
+=
duieditor
.
cpp
\
duieditorfactory
.
cpp
\
duieditorplugin
.
cpp
\
...
...
@@ -30,5 +32,7 @@ SOURCES += duieditor.cpp \
duidocument
.
cpp
\
duicompletionvisitor
.
cpp
\
duimodelmanagerinterface
.
cpp
\
duimodelmanager
.
cpp
duimodelmanager
.
cpp
\
duicodeformatter
.
cpp
\
navigationtokenfinder
.
cpp
RESOURCES
+=
duieditor
.
qrc
src/plugins/duieditor/duieditorplugin.cpp
View file @
71549ec6
...
...
@@ -113,8 +113,10 @@ bool DuiEditorPlugin::initialize(const QStringList & /*arguments*/, QString *err
m_actionHandler
=
new
TextEditor
::
TextEditorActionHandler
(
DuiEditor
::
Constants
::
C_DUIEDITOR
,
TextEditor
::
TextEditorActionHandler
::
Format
|
TextEditor
::
TextEditorActionHandler
::
Reformat
|
TextEditor
::
TextEditorActionHandler
::
UnCommentSelection
|
TextEditor
::
TextEditorActionHandler
::
UnCollapseAll
);
m_actionHandler
->
initializeActions
();
m_completion
=
new
DuiCodeCompletion
();
addAutoReleasedObject
(
m_completion
);
...
...
src/plugins/duieditor/navigationtokenfinder.cpp
0 → 100644
View file @
71549ec6
#include <QDebug>
#include "qmljsast_p.h"
#include "qmljsengine_p.h"
#include "navigationtokenfinder.h"
using
namespace
QmlJS
;
using
namespace
QmlJS
::
AST
;
using
namespace
DuiEditor
::
Internal
;
bool
NavigationTokenFinder
::
operator
()(
QmlJS
::
AST
::
UiProgram
*
ast
,
int
position
,
bool
resolveTarget
)
{
_resolveTarget
=
resolveTarget
;
_scopes
.
clear
();
_pos
=
position
;
_linkPosition
=
-
1
;
_targetLine
=
-
1
;
Node
::
accept
(
ast
,
this
);
if
(
resolveTarget
)
return
targetFound
();
else
return
linkFound
();
}
bool
NavigationTokenFinder
::
visit
(
QmlJS
::
AST
::
IdentifierExpression
*
ast
)
{
if
(
linkFound
())
return
false
;
if
(
ast
->
identifierToken
.
offset
<=
_pos
&&
_pos
<=
ast
->
identifierToken
.
end
())
{
_linkPosition
=
ast
->
identifierToken
.
offset
;
_linkLength
=
ast
->
identifierToken
.
length
;
if
(
Node
*
node
=
findDeclarationInScopes
(
ast
->
name
))
rememberStartPosition
(
node
);
}
return
false
;
}
bool
NavigationTokenFinder
::
visit
(
QmlJS
::
AST
::
UiArrayBinding
*
ast
)
{
if
(
linkFound
())
return
false
;
Node
::
accept
(
ast
->
members
,
this
);
return
false
;
}
bool
NavigationTokenFinder
::
visit
(
QmlJS
::
AST
::
UiPublicMember
*
ast
)
{
if
(
linkFound
())
return
false
;
Node
::
accept
(
ast
->
expression
,
this
);
return
false
;
}
bool
NavigationTokenFinder
::
visit
(
QmlJS
::
AST
::
Block
*
ast
)
{
_scopes
.
push
(
ast
);
if
(
linkFound
())
return
false
;
return
true
;
}
void
NavigationTokenFinder
::
endVisit
(
QmlJS
::
AST
::
Block
*
)
{
_scopes
.
pop
();
}
bool
NavigationTokenFinder
::
visit
(
QmlJS
::
AST
::
UiObjectBinding
*
ast
)
{
_scopes
.
push
(
ast
);
if
(
linkFound
())
return
false
;
Node
::
accept
(
ast
->
qualifiedTypeNameId
,
this
);
Node
::
accept
(
ast
->
initializer
,
this
);
return
false
;
}
void
NavigationTokenFinder
::
endVisit
(
QmlJS
::
AST
::
UiObjectBinding
*
)
{
_scopes
.
pop
();
}
bool
NavigationTokenFinder
::
visit
(
QmlJS
::
AST
::
UiObjectDefinition
*
ast
)
{
_scopes
.
push
(
ast
);
if
(
linkFound
())
return
false
;
return
true
;
}
void
NavigationTokenFinder
::
endVisit
(
QmlJS
::
AST
::
UiObjectDefinition
*
)
{
_scopes
.
pop
();
}
bool
NavigationTokenFinder
::
visit
(
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
)
_linkLength
=
iter2
->
identifierToken
.
end
()
-
_linkPosition
;
if
(
Node
*
node
=
findDeclarationInScopes
(
ast
))
rememberStartPosition
(
node
);
return
false
;
}
}
}
return
false
;
}
bool
NavigationTokenFinder
::
visit
(
QmlJS
::
AST
::
UiScriptBinding
*
ast
)
{
if
(
linkFound
())
return
false
;
Node
::
accept
(
ast
->
statement
,
this
);
return
false
;
}
bool
NavigationTokenFinder
::
visit
(
QmlJS
::
AST
::
UiSourceElement
*
/*ast*/
)
{
return
false
;
}
void
NavigationTokenFinder
::
rememberStartPosition
(
QmlJS
::
AST
::
Node
*
node
)
{
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"
;
}
}
static
inline
bool
isId
(
QmlJS
::
AST
::
UiQualifiedId
*
ast
)
{
return
!
(
ast
->
next
)
&&
ast
->
name
->
asString
()
==
"id"
;
}
static
inline
QString
idToString
(
QmlJS
::
AST
::
Statement
*
stmt
)
{
if
(
ExpressionStatement
*
e
=
cast
<
ExpressionStatement
*>
(
stmt
))
if
(
IdentifierExpression
*
i
=
cast
<
IdentifierExpression
*>
(
e
->
expression
))
return
i
->
name
->
asString
();
return
QString
::
null
;
}
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
;
}
else
if
(
UiScriptBinding
*
s
=
cast
<
UiScriptBinding
*>
(
m
))
{
if
(
isId
(
s
->
qualifiedId
)
&&
nameId
==
idToString
(
s
->
statement
))
return
s
;
}
return
0
;
}
static
QmlJS
::
AST
::
Node
*
findDeclaration
(
const
QString
&
nameId
,
QmlJS
::
AST
::
UiObjectMemberList
*
l
)
{
for
(
UiObjectMemberList
*
iter
=
l
;
iter
;
iter
=
iter
->
next
)
if
(
Node
*
n
=
findDeclaration
(
nameId
,
iter
->
member
))
return
n
;
return
0
;
}
static
QmlJS
::
AST
::
Node
*
findDeclaration
(
const
QString
&
nameId
,
QmlJS
::
AST
::
Statement
*
s
)
{
if
(
VariableStatement
*
v
=
cast
<
VariableStatement
*>
(
s
))
{
for
(
VariableDeclarationList
*
l
=
v
->
declarations
;
l
;
l
=
l
->
next
)
{
if
(
l
->
declaration
->
name
->
asString
()
==
nameId
)
return
l
->
declaration
;
}
}
return
0
;
}
static
QmlJS
::
AST
::
Node
*
findDeclaration
(
const
QString
&
nameId
,
QmlJS
::
AST
::
StatementList
*
l
)
{
for
(
StatementList
*
iter
=
l
;
iter
;
iter
=
iter
->
next
)
if
(
Node
*
n
=
findDeclaration
(
nameId
,
iter
->
statement
))
return
n
;
return
0
;
}
static
QmlJS
::
AST
::
Node
*
findDeclarationAsDirectChild
(
const
QString
&
nameId
,
QmlJS
::
AST
::
Node
*
node
)
{
if
(
UiObjectBinding
*
binding
=
cast
<
UiObjectBinding
*>
(
node
))
{
return
findDeclaration
(
nameId
,
binding
->
initializer
->
members
);
}
else
if
(
UiObjectDefinition
*
def
=
cast
<
UiObjectDefinition
*>
(
node
))
{
return
findDeclaration
(
nameId
,
def
->
initializer
->
members
);
}
else
if
(
Block
*
block
=
cast
<
Block
*>
(
node
))
{
return
findDeclaration
(
nameId
,
block
->
statements
);
}
else
{
return
0
;
}
}
static
QmlJS
::
AST
::
Node
*
findDeclarationInNode
(
QmlJS
::
AST
::
UiQualifiedId
*
qualifiedId
,
QmlJS
::
AST
::
Node
*
node
)
{
if
(
!
qualifiedId
||
!
node
)
return
node
;
else
return
findDeclarationInNode
(
qualifiedId
->
next
,
findDeclarationAsDirectChild
(
qualifiedId
->
name
->
asString
(),
node
));
}
QmlJS
::
AST
::
Node
*
NavigationTokenFinder
::
findDeclarationInScopes
(
QmlJS
::
NameId
*
nameId
)
{
if
(
!
_resolveTarget
)
return
0
;
const
QString
nameAsString
=
nameId
->
asString
();
foreach
(
QmlJS
::
AST
::
Node
*
scope
,
_scopes
)
{
Node
*
result
=
findDeclarationAsDirectChild
(
nameAsString
,
scope
);
if
(
result
)
return
result
;
}
return
0
;
}
QmlJS
::
AST
::
Node
*
NavigationTokenFinder
::
findDeclarationInScopes
(
QmlJS
::
AST
::
UiQualifiedId
*
qualifiedId
)
{
if
(
!
_resolveTarget
)
return
0
;
const
QString
nameAsString
=
qualifiedId
->
name
->
asString
();
qDebug
()
<<
"findDecl. for id part"
<<
nameAsString
;
foreach
(
QmlJS
::
AST
::
Node
*
scope
,
_scopes
)
{
Node
*
result
=
findDeclarationAsDirectChild
(
nameAsString
,
scope
);
if
(
result
)
return
findDeclarationInNode
(
qualifiedId
->
next
,
result
);
}
return
0
;
}
src/plugins/duieditor/navigationtokenfinder.h
0 → 100644
View file @
71549ec6
#ifndef NAVIGATIONTOKENFINDER_H
#define NAVIGATIONTOKENFINDER_H
#include <QStack>
#include <QString>
#include "qmljsastvisitor_p.h"
namespace
QmlJS
{
class
NameId
;
}
// namespace QmlJS
namespace
DuiEditor
{
namespace
Internal
{
class
NavigationTokenFinder
:
protected
QmlJS
::
AST
::
Visitor
{
public:
bool
operator
()(
QmlJS
::
AST
::
UiProgram
*
ast
,
int
position
,
bool
resolveTarget
);
bool
targetFound
()
const
{
return
_targetLine
!=
-
1
;
}
bool
linkFound
()
const
{
return
_linkPosition
!=
-
1
;
}
int
linkPosition
()
const
{
return
_linkPosition
;
}
int
linkLength
()
const
{
return
_linkLength
;
}
int
targetLine
()
const
{
return
_targetLine
;
}
int
targetColumn
()
const
{
return
_targetColumn
;
}