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
13225875
Commit
13225875
authored
Jun 09, 2009
by
Roberto Raggi
Browse files
More work on `Quick Fix'.
parent
e5fcbba7
Changes
10
Hide whitespace changes
Inline
Side-by-side
src/plugins/cppeditor/cppplugin.cpp
View file @
13225875
...
...
@@ -134,6 +134,11 @@ void CppPlugin::initializeEditor(CPPEditor *editor)
// auto completion
connect
(
editor
,
SIGNAL
(
requestAutoCompletion
(
ITextEditable
*
,
bool
)),
TextEditor
::
Internal
::
CompletionSupport
::
instance
(),
SLOT
(
autoComplete
(
ITextEditable
*
,
bool
)));
// quick fix
connect
(
editor
,
SIGNAL
(
requestQuickFix
(
ITextEditable
*
)),
TextEditor
::
Internal
::
CompletionSupport
::
instance
(),
SLOT
(
quickFix
(
ITextEditable
*
)));
// method combo box sorting
connect
(
this
,
SIGNAL
(
methodOverviewSortingChanged
(
bool
)),
editor
,
SLOT
(
setSortedMethodOverview
(
bool
)));
...
...
src/plugins/cpptools/cppcodecompletion.cpp
View file @
13225875
...
...
@@ -30,6 +30,7 @@
#include "cppcodecompletion.h"
#include "cppmodelmanager.h"
#include "cppdoxygen.h"
#include "cpptoolseditorsupport.h"
#include <Control.h>
#include <AST.h>
...
...
@@ -421,6 +422,59 @@ void FunctionArgumentWidget::updateHintText()
m_popupFrame
->
move
(
pos
);
}
CppQuickFixCollector
::
CppQuickFixCollector
(
CppModelManager
*
modelManager
)
:
_modelManager
(
modelManager
),
_editor
(
0
)
{
}
CppQuickFixCollector
::~
CppQuickFixCollector
()
{
}
bool
CppQuickFixCollector
::
supportsEditor
(
TextEditor
::
ITextEditable
*
editor
)
{
return
_modelManager
->
isCppEditor
(
editor
);
}
bool
CppQuickFixCollector
::
triggersCompletion
(
TextEditor
::
ITextEditable
*
)
{
return
false
;
}
int
CppQuickFixCollector
::
startCompletion
(
TextEditor
::
ITextEditable
*
editor
)
{
_editor
=
editor
;
if
(
CppEditorSupport
*
extra
=
_modelManager
->
editorSupport
(
editor
))
{
const
QList
<
QuickFixOperationPtr
>
quickFixes
=
extra
->
quickFixes
();
if
(
!
quickFixes
.
isEmpty
())
{
int
i
=
0
;
foreach
(
QuickFixOperationPtr
op
,
quickFixes
)
{
TextEditor
::
CompletionItem
item
(
this
);
item
.
m_text
=
op
->
description
();
item
.
m_data
=
QVariant
::
fromValue
(
i
);
_completions
.
append
(
item
);
++
i
;
}
return
editor
->
position
();
}
}
return
-
1
;
}
void
CppQuickFixCollector
::
completions
(
QList
<
TextEditor
::
CompletionItem
>
*
completions
)
{
completions
->
append
(
_completions
);
}
void
CppQuickFixCollector
::
complete
(
const
TextEditor
::
CompletionItem
&
item
)
{
CppEditorSupport
*
extra
=
_modelManager
->
editorSupport
(
_editor
);
const
QList
<
QuickFixOperationPtr
>
quickFixes
=
extra
->
quickFixes
();
QuickFixOperationPtr
quickFix
=
quickFixes
.
at
(
item
.
m_data
.
toInt
());
TextEditor
::
BaseTextEditor
*
ed
=
qobject_cast
<
TextEditor
::
BaseTextEditor
*>
(
_editor
->
widget
());
quickFix
->
apply
(
ed
->
textCursor
());
}
void
CppQuickFixCollector
::
cleanup
()
{
_completions
.
clear
();
}
CppCodeCompletion
::
CppCodeCompletion
(
CppModelManager
*
manager
)
:
ICompletionCollector
(
manager
),
m_manager
(
manager
),
...
...
src/plugins/cpptools/cppcodecompletion.h
View file @
13225875
...
...
@@ -52,6 +52,27 @@ namespace Internal {
class
CppModelManager
;
class
FunctionArgumentWidget
;
class
CppQuickFixCollector
:
public
TextEditor
::
IQuickFixCollector
{
Q_OBJECT
public:
CppQuickFixCollector
(
CppModelManager
*
modelManager
);
virtual
~
CppQuickFixCollector
();
virtual
bool
supportsEditor
(
TextEditor
::
ITextEditable
*
editor
);
virtual
bool
triggersCompletion
(
TextEditor
::
ITextEditable
*
editor
);
virtual
int
startCompletion
(
TextEditor
::
ITextEditable
*
editor
);
virtual
void
completions
(
QList
<
TextEditor
::
CompletionItem
>
*
completions
);
virtual
void
complete
(
const
TextEditor
::
CompletionItem
&
item
);
virtual
void
cleanup
();
private:
CppModelManager
*
_modelManager
;
TextEditor
::
ITextEditable
*
_editor
;
QList
<
TextEditor
::
CompletionItem
>
_completions
;
};
class
CppCodeCompletion
:
public
TextEditor
::
ICompletionCollector
{
Q_OBJECT
...
...
src/plugins/cpptools/cppmodelmanager.h
View file @
13225875
...
...
@@ -86,6 +86,9 @@ public:
bool
isCppEditor
(
Core
::
IEditor
*
editor
)
const
;
// ### private
CppEditorSupport
*
editorSupport
(
TextEditor
::
ITextEditor
*
editor
)
const
{
return
m_editorSupport
.
value
(
editor
);
}
void
emitDocumentUpdated
(
CPlusPlus
::
Document
::
Ptr
doc
);
void
stopEditorSelectionsUpdate
()
...
...
src/plugins/cpptools/cpptoolseditorsupport.cpp
View file @
13225875
...
...
@@ -33,9 +33,214 @@
#include <texteditor/itexteditor.h>
#include <texteditor/basetexteditor.h>
#include <QTimer>
#include <AST.h>
#include <ASTVisitor.h>
#include <TranslationUnit.h>
#include <QtCore/QTimer>
using
namespace
CppTools
::
Internal
;
using
namespace
CPlusPlus
;
namespace
{
enum
{
DEFAULT_QUICKFIX_INTERVAL
=
500
};
class
QuickFixMark
:
public
TextEditor
::
ITextMark
{
QIcon
_icon
;
public:
QuickFixMark
(
QObject
*
parent
)
:
TextEditor
::
ITextMark
(
parent
),
_icon
(
QLatin1String
(
":/core/images/redo.png"
))
// ### FIXME
{
}
virtual
~
QuickFixMark
()
{
}
virtual
QIcon
icon
()
const
{
return
_icon
;
}
virtual
void
updateLineNumber
(
int
)
{
}
virtual
void
updateBlock
(
const
QTextBlock
&
)
{
}
virtual
void
removedFromEditor
()
{
}
virtual
void
documentClosing
()
{
}
};
class
ReplaceCast
:
public
QuickFixOperation
{
CastExpressionAST
*
_castExpression
;
public:
ReplaceCast
(
CastExpressionAST
*
node
,
Document
::
Ptr
doc
,
const
Snapshot
&
snapshot
)
:
QuickFixOperation
(
doc
,
snapshot
),
_castExpression
(
node
)
{
}
virtual
QString
description
()
const
{
return
QLatin1String
(
"Rewrite old C-style cast"
);
}
virtual
void
apply
(
QTextCursor
tc
)
{
setTextCursor
(
tc
);
tc
.
beginEditBlock
();
QTextCursor
beginOfCast
=
cursor
(
_castExpression
->
lparen_token
);
QTextCursor
endOfCast
=
cursor
(
_castExpression
->
rparen_token
);
QTextCursor
beginOfExpr
=
moveAtStartOfToken
(
_castExpression
->
expression
->
firstToken
());
QTextCursor
endOfExpr
=
moveAtEndOfToken
(
_castExpression
->
expression
->
lastToken
()
-
1
);
beginOfCast
.
insertText
(
QLatin1String
(
"reinterpret_cast<"
));
endOfCast
.
insertText
(
QLatin1String
(
">"
));
beginOfExpr
.
insertText
(
QLatin1String
(
"("
));
endOfExpr
.
insertText
(
QLatin1String
(
")"
));
tc
.
endEditBlock
();
}
};
class
CheckDocument
:
protected
ASTVisitor
{
QTextCursor
_textCursor
;
Document
::
Ptr
_doc
;
Snapshot
_snapshot
;
unsigned
_line
;
unsigned
_column
;
QList
<
QuickFixOperationPtr
>
_quickFixes
;
public:
CheckDocument
(
Document
::
Ptr
doc
,
Snapshot
snapshot
)
:
ASTVisitor
(
doc
->
control
()),
_doc
(
doc
),
_snapshot
(
snapshot
)
{
}
QList
<
QuickFixOperationPtr
>
operator
()(
QTextCursor
tc
)
{
_quickFixes
.
clear
();
_textCursor
=
tc
;
_line
=
tc
.
blockNumber
()
+
1
;
_column
=
tc
.
columnNumber
()
+
1
;
accept
(
_doc
->
translationUnit
()
->
ast
());
return
_quickFixes
;
}
protected:
using
ASTVisitor
::
visit
;
bool
checkPosition
(
AST
*
ast
)
const
{
unsigned
startLine
,
startColumn
;
unsigned
endLine
,
endColumn
;
getTokenStartPosition
(
ast
->
firstToken
(),
&
startLine
,
&
startColumn
);
getTokenEndPosition
(
ast
->
lastToken
()
-
1
,
&
endLine
,
&
endColumn
);
if
(
_line
<
startLine
||
(
_line
==
startLine
&&
_column
<
startColumn
))
return
false
;
else
if
(
_line
>
endLine
||
(
_line
==
endLine
&&
_column
>=
endColumn
))
return
false
;
return
true
;
}
/*
virtual bool visit(ForStatementAST *ast)
{
if (! checkPosition(ast))
return true;
if (ast->initializer && ast->initializer->asDeclarationStatement() != 0) {
if (checkPosition(ast->initializer)) {
// move initializer
_nodes.append(ast);
}
}
return true;
}
*/
virtual
bool
visit
(
CastExpressionAST
*
ast
)
{
if
(
!
checkPosition
(
ast
))
return
true
;
if
(
ast
->
type_id
&&
ast
->
lparen_token
&&
ast
->
rparen_token
&&
ast
->
expression
)
{
QuickFixOperationPtr
op
(
new
ReplaceCast
(
ast
,
_doc
,
_snapshot
));
_quickFixes
.
append
(
op
);
}
return
true
;
}
};
}
// end of anonymous namespace
QuickFixOperation
::
QuickFixOperation
(
CPlusPlus
::
Document
::
Ptr
doc
,
const
CPlusPlus
::
Snapshot
&
snapshot
)
:
_doc
(
doc
),
_snapshot
(
snapshot
)
{
}
QuickFixOperation
::~
QuickFixOperation
()
{
}
QTextCursor
QuickFixOperation
::
textCursor
()
const
{
return
_textCursor
;
}
void
QuickFixOperation
::
setTextCursor
(
const
QTextCursor
&
tc
)
{
_textCursor
=
tc
;
}
const
CPlusPlus
::
Token
&
QuickFixOperation
::
tokenAt
(
unsigned
index
)
const
{
return
_doc
->
translationUnit
()
->
tokenAt
(
index
);
}
void
QuickFixOperation
::
getTokenStartPosition
(
unsigned
index
,
unsigned
*
line
,
unsigned
*
column
)
const
{
_doc
->
translationUnit
()
->
getPosition
(
tokenAt
(
index
).
begin
(),
line
,
column
);
}
void
QuickFixOperation
::
getTokenEndPosition
(
unsigned
index
,
unsigned
*
line
,
unsigned
*
column
)
const
{
_doc
->
translationUnit
()
->
getPosition
(
tokenAt
(
index
).
end
(),
line
,
column
);
}
QTextCursor
QuickFixOperation
::
cursor
(
unsigned
index
)
const
{
const
Token
&
tk
=
tokenAt
(
index
);
unsigned
line
,
col
;
getTokenStartPosition
(
index
,
&
line
,
&
col
);
QTextCursor
tc
=
_textCursor
;
tc
.
setPosition
(
tc
.
document
()
->
findBlockByNumber
(
line
-
1
).
position
()
+
col
-
1
);
tc
.
setPosition
(
tc
.
position
()
+
tk
.
length
,
QTextCursor
::
KeepAnchor
);
return
tc
;
}
QTextCursor
QuickFixOperation
::
moveAtStartOfToken
(
unsigned
index
)
const
{
unsigned
line
,
col
;
getTokenStartPosition
(
index
,
&
line
,
&
col
);
QTextCursor
tc
=
_textCursor
;
tc
.
setPosition
(
tc
.
document
()
->
findBlockByNumber
(
line
-
1
).
position
()
+
col
-
1
);
return
tc
;
}
QTextCursor
QuickFixOperation
::
moveAtEndOfToken
(
unsigned
index
)
const
{
const
Token
&
tk
=
tokenAt
(
index
);
unsigned
line
,
col
;
getTokenStartPosition
(
index
,
&
line
,
&
col
);
QTextCursor
tc
=
_textCursor
;
tc
.
setPosition
(
tc
.
document
()
->
findBlockByNumber
(
line
-
1
).
position
()
+
col
+
tk
.
length
-
1
);
return
tc
;
}
CppEditorSupport
::
CppEditorSupport
(
CppModelManager
*
modelManager
)
:
QObject
(
modelManager
),
...
...
@@ -46,6 +251,13 @@ CppEditorSupport::CppEditorSupport(CppModelManager *modelManager)
_updateDocumentTimer
->
setSingleShot
(
true
);
_updateDocumentTimer
->
setInterval
(
_updateDocumentInterval
);
connect
(
_updateDocumentTimer
,
SIGNAL
(
timeout
()),
this
,
SLOT
(
updateDocumentNow
()));
_quickFixMark
=
new
QuickFixMark
(
this
);
_quickFixTimer
=
new
QTimer
(
this
);
_quickFixTimer
->
setSingleShot
(
true
);
_quickFixTimer
->
setInterval
(
DEFAULT_QUICKFIX_INTERVAL
);
connect
(
_quickFixTimer
,
SIGNAL
(
timeout
()),
this
,
SLOT
(
checkDocumentNow
()));
}
CppEditorSupport
::~
CppEditorSupport
()
...
...
@@ -62,7 +274,11 @@ void CppEditorSupport::setTextEditor(TextEditor::ITextEditor *textEditor)
return
;
connect
(
_textEditor
,
SIGNAL
(
contentsChanged
()),
this
,
SIGNAL
(
contentsChanged
()));
connect
(
qobject_cast
<
TextEditor
::
BaseTextEditor
*>
(
_textEditor
->
widget
()),
SIGNAL
(
cursorPositionChanged
()),
this
,
SLOT
(
checkDocument
()));
connect
(
this
,
SIGNAL
(
contentsChanged
()),
this
,
SLOT
(
updateDocument
()));
updateDocument
();
}
...
...
@@ -107,5 +323,35 @@ void CppEditorSupport::updateDocumentNow()
}
}
void
CppEditorSupport
::
checkDocument
()
{
_quickFixTimer
->
start
(
DEFAULT_QUICKFIX_INTERVAL
);
}
void
CppEditorSupport
::
checkDocumentNow
()
{
_textEditor
->
markableInterface
()
->
removeMark
(
_quickFixMark
);
_quickFixes
.
clear
();
TextEditor
::
BaseTextEditor
*
ed
=
qobject_cast
<
TextEditor
::
BaseTextEditor
*>
(
_textEditor
->
widget
());
Snapshot
snapshot
=
_modelManager
->
snapshot
();
const
QByteArray
plainText
=
contents
();
const
QString
fileName
=
_textEditor
->
file
()
->
fileName
();
const
QByteArray
preprocessedCode
=
snapshot
.
preprocessedCode
(
plainText
,
fileName
);
if
(
Document
::
Ptr
doc
=
snapshot
.
documentFromSource
(
preprocessedCode
,
fileName
))
{
CheckDocument
checkDocument
(
doc
,
snapshot
);
QList
<
QuickFixOperationPtr
>
quickFixes
=
checkDocument
(
ed
->
textCursor
());
if
(
!
quickFixes
.
isEmpty
())
{
int
line
,
col
;
ed
->
convertPosition
(
ed
->
position
(),
&
line
,
&
col
);
_textEditor
->
markableInterface
()
->
addMark
(
_quickFixMark
,
line
);
_quickFixes
=
quickFixes
;
}
}
}
src/plugins/cpptools/cpptoolseditorsupport.h
View file @
13225875
...
...
@@ -33,13 +33,21 @@
#include <QObject>
#include <QPointer>
#include <QFuture>
#include <QSharedPointer>
#include <QTextCursor.h>
#include <cplusplus/CppDocument.h>
QT_BEGIN_NAMESPACE
class
QTimer
;
QT_END_NAMESPACE
namespace
CPlusPlus
{
class
AST
;
}
namespace
TextEditor
{
class
ITextEditor
;
class
ITextMark
;
}
// end of namespace TextEditor
namespace
CppTools
{
...
...
@@ -47,6 +55,46 @@ namespace Internal {
class
CppModelManager
;
class
QuickFixOperation
;
typedef
QSharedPointer
<
QuickFixOperation
>
QuickFixOperationPtr
;
class
QuickFixOperation
{
Q_DISABLE_COPY
(
QuickFixOperation
)
public:
QuickFixOperation
(
CPlusPlus
::
Document
::
Ptr
doc
,
const
CPlusPlus
::
Snapshot
&
snapshot
);
virtual
~
QuickFixOperation
();
virtual
QString
description
()
const
=
0
;
virtual
void
apply
(
QTextCursor
cursor
)
=
0
;
CPlusPlus
::
Document
::
Ptr
document
()
const
{
return
_doc
;
}
CPlusPlus
::
Snapshot
snapshot
()
const
{
return
_snapshot
;
}
QTextCursor
textCursor
()
const
;
void
setTextCursor
(
const
QTextCursor
&
tc
);
protected:
const
CPlusPlus
::
Token
&
tokenAt
(
unsigned
index
)
const
;
void
getTokenStartPosition
(
unsigned
index
,
unsigned
*
line
,
unsigned
*
column
)
const
;
void
getTokenEndPosition
(
unsigned
index
,
unsigned
*
line
,
unsigned
*
column
)
const
;
QTextCursor
cursor
(
unsigned
index
)
const
;
QTextCursor
moveAtStartOfToken
(
unsigned
index
)
const
;
QTextCursor
moveAtEndOfToken
(
unsigned
index
)
const
;
private:
CPlusPlus
::
AST
*
_node
;
CPlusPlus
::
Document
::
Ptr
_doc
;
CPlusPlus
::
Snapshot
_snapshot
;
QTextCursor
_textCursor
;
};
class
CppEditorSupport
:
public
QObject
{
Q_OBJECT
...
...
@@ -55,6 +103,9 @@ public:
CppEditorSupport
(
CppModelManager
*
modelManager
);
virtual
~
CppEditorSupport
();
QList
<
QuickFixOperationPtr
>
quickFixes
()
const
{
return
_quickFixes
;
}
TextEditor
::
ITextEditor
*
textEditor
()
const
;
void
setTextEditor
(
TextEditor
::
ITextEditor
*
textEditor
);
...
...
@@ -70,6 +121,9 @@ private Q_SLOTS:
void
updateDocument
();
void
updateDocumentNow
();
void
checkDocument
();
void
checkDocumentNow
();
private:
enum
{
UPDATE_DOCUMENT_DEFAULT_INTERVAL
=
150
};
...
...
@@ -79,6 +133,10 @@ private:
int
_updateDocumentInterval
;
QFuture
<
void
>
_documentParser
;
QByteArray
_cachedContents
;
QTimer
*
_quickFixTimer
;
TextEditor
::
ITextMark
*
_quickFixMark
;
QList
<
QuickFixOperationPtr
>
_quickFixes
;
};
}
// namespace Internal
...
...
src/plugins/cpptools/cpptoolsplugin.cpp
View file @
13225875
...
...
@@ -151,8 +151,12 @@ bool CppToolsPlugin::initialize(const QStringList &arguments, QString *error)
// Objects
m_modelManager
=
new
CppModelManager
(
this
);
addAutoReleasedObject
(
m_modelManager
);
m_completion
=
new
CppCodeCompletion
(
m_modelManager
);
addAutoReleasedObject
(
m_completion
);
addAutoReleasedObject
(
new
CppQuickFixCollector
(
m_modelManager
));
CppQuickOpenFilter
*
quickOpenFilter
=
new
CppQuickOpenFilter
(
m_modelManager
,
core
->
editorManager
());
addAutoReleasedObject
(
quickOpenFilter
);
...
...
src/plugins/texteditor/completionsupport.cpp
View file @
13225875
...
...
@@ -96,7 +96,6 @@ void CompletionSupport::autoComplete(ITextEditable *editor, bool forced)
void
CompletionSupport
::
quickFix
(
ITextEditable
*
editor
)
{
qDebug
()
<<
Q_FUNC_INFO
;
autoComplete_helper
(
editor
,
/*forced = */
true
,
/*quickFix = */
true
);
...
...
src/plugins/texteditor/icompletioncollector.h
View file @
13225875
...
...
@@ -121,6 +121,9 @@ public:
IQuickFixCollector
(
QObject
*
parent
=
0
)
:
ICompletionCollector
(
parent
)
{}
virtual
~
IQuickFixCollector
()
{}
virtual
bool
triggersCompletion
(
TextEditor
::
ITextEditable
*
)
{
return
false
;
}
virtual
bool
partiallyComplete
(
const
QList
<
TextEditor
::
CompletionItem
>
&
)
{
return
false
;
}
};
...
...
src/plugins/texteditor/texteditorplugin.cpp
View file @
13225875
...
...
@@ -137,6 +137,7 @@ bool TextEditorPlugin::initialize(const QStringList &arguments, QString *errorMe
// Make sure the shortcut still works when the quick fix widget is active
quickFixShortcut
->
setContext
(
Qt
::
ApplicationShortcut
);
Core
::
Command
*
quickFixCommand
=
am
->
registerShortcut
(
quickFixShortcut
,
Constants
::
QUICKFIX_THIS
,
context
);
quickFixCommand
->
setDefaultKeySequence
(
QKeySequence
(
tr
(
"Alt+Return"
)));
connect
(
quickFixShortcut
,
SIGNAL
(
activated
()),
this
,
SLOT
(
invokeQuickFix
()));
return
true
;
...
...
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