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
9135c8cc
Commit
9135c8cc
authored
Jul 08, 2010
by
Erik Verbruggen
Browse files
Quickfix for adding a declaration to a class from a definition.
parent
65eb1d55
Changes
10
Hide whitespace changes
Inline
Side-by-side
src/libs/cplusplus/LookupContext.cpp
View file @
9135c8cc
...
...
@@ -138,6 +138,43 @@ QList<const Name *> LookupContext::fullyQualifiedName(Symbol *symbol)
return
names
;
}
const
Name
*
LookupContext
::
minimalName
(
const
Name
*
name
,
Scope
*
source
,
ClassOrNamespace
*
target
)
const
{
Q_ASSERT
(
name
);
Q_ASSERT
(
source
);
Q_ASSERT
(
target
);
QList
<
Symbol
*>
symbols
=
lookup
(
name
,
source
);
if
(
symbols
.
isEmpty
())
return
0
;
Symbol
*
canonicalSymbol
=
symbols
.
first
();
std
::
vector
<
const
Name
*>
fqNames
=
fullyQualifiedName
(
canonicalSymbol
).
toVector
().
toStdVector
();
if
(
const
QualifiedNameId
*
qId
=
name
->
asQualifiedNameId
())
fqNames
.
push_back
(
qId
->
nameAt
(
qId
->
nameCount
()
-
1
));
else
fqNames
.
push_back
(
name
);
const
QualifiedNameId
*
lastWorking
=
0
;
for
(
unsigned
i
=
0
;
i
<
fqNames
.
size
();
++
i
)
{
const
QualifiedNameId
*
newName
=
control
()
->
qualifiedNameId
(
&
fqNames
[
i
],
fqNames
.
size
()
-
i
);
QList
<
Symbol
*>
candidates
=
target
->
lookup
(
newName
);
if
(
candidates
.
contains
(
canonicalSymbol
))
lastWorking
=
newName
;
else
break
;
}
if
(
lastWorking
&&
lastWorking
->
nameCount
()
==
1
)
return
lastWorking
->
nameAt
(
0
);
else
return
lastWorking
;
}
QSharedPointer
<
CreateBindings
>
LookupContext
::
bindings
()
const
{
if
(
!
_bindings
)
...
...
@@ -280,6 +317,19 @@ QList<Symbol *> LookupContext::lookup(const Name *name, Scope *scope) const
return
candidates
;
}
ClassOrNamespace
*
LookupContext
::
lookupParent
(
Symbol
*
symbol
)
const
{
QList
<
const
Name
*>
fqName
=
fullyQualifiedName
(
symbol
);
ClassOrNamespace
*
binding
=
globalNamespace
();
foreach
(
const
Name
*
name
,
fqName
)
{
binding
=
binding
->
findType
(
name
);
if
(
!
binding
)
return
0
;
}
return
binding
;
}
ClassOrNamespace
::
ClassOrNamespace
(
CreateBindings
*
factory
,
ClassOrNamespace
*
parent
)
:
_factory
(
factory
),
_parent
(
parent
),
_templateId
(
0
)
{
...
...
src/libs/cplusplus/LookupContext.h
View file @
9135c8cc
...
...
@@ -216,6 +216,7 @@ public:
QList
<
Symbol
*>
lookup
(
const
Name
*
name
,
Scope
*
scope
)
const
;
ClassOrNamespace
*
lookupType
(
const
Name
*
name
,
Scope
*
scope
)
const
;
ClassOrNamespace
*
lookupType
(
Symbol
*
symbol
)
const
;
ClassOrNamespace
*
lookupParent
(
Symbol
*
symbol
)
const
;
/// \internal
QSharedPointer
<
CreateBindings
>
bindings
()
const
;
...
...
@@ -227,6 +228,9 @@ public:
static
QList
<
const
Name
*>
fullyQualifiedName
(
Symbol
*
symbol
);
const
Name
*
minimalName
(
const
Name
*
name
,
Scope
*
source
,
ClassOrNamespace
*
target
)
const
;
private:
// The current expression.
Document
::
Ptr
_expressionDocument
;
...
...
src/libs/cplusplus/Overview.cpp
View file @
9135c8cc
...
...
@@ -30,6 +30,9 @@
#include "Overview.h"
#include "NamePrettyPrinter.h"
#include "TypePrettyPrinter.h"
#include <Control.h>
#include <CoreTypes.h>
#include <FullySpecifiedType.h>
using
namespace
CPlusPlus
;
...
...
@@ -145,3 +148,23 @@ QString Overview::prettyType(const FullySpecifiedType &ty,
TypePrettyPrinter
pp
(
this
);
return
pp
(
ty
,
name
);
}
/**
* Pretty-prints the given fully-specified type, but replacing the contained
* type with the given name.
*
* \param type the fully-specified type to convert to string
* \param the name for the named-type to use
* \param the control where the name is registered
* \return the pretty-printed name
*/
QString
Overview
::
prettyTypeWithName
(
const
FullySpecifiedType
&
type
,
const
Name
*
name
,
Control
*
control
)
{
NamedType
*
namedTy
=
control
->
namedType
(
name
);
FullySpecifiedType
newTy
=
type
;
newTy
.
setType
(
namedTy
);
return
prettyType
(
newTy
);
}
src/libs/cplusplus/Overview.h
View file @
9135c8cc
...
...
@@ -79,6 +79,10 @@ public:
QString
prettyType
(
const
FullySpecifiedType
&
type
,
const
Name
*
name
=
0
)
const
;
QString
prettyType
(
const
FullySpecifiedType
&
type
,
const
QString
&
name
)
const
;
QString
prettyTypeWithName
(
const
FullySpecifiedType
&
type
,
const
Name
*
name
,
Control
*
control
);
private:
unsigned
_markedArgument
;
int
_markedArgumentBegin
;
...
...
src/plugins/cppeditor/cppdeclfromdef.cpp
0 → 100644
View file @
9135c8cc
/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** Commercial Usage
**
** Licensees holding valid Qt Commercial licenses may use this file in
** accordance with the Qt Commercial License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Nokia.
**
** GNU Lesser General Public License Usage
**
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** If you are unsure which license is appropriate for your use, please
** contact the sales department at http://qt.nokia.com/contact.
**
**************************************************************************/
#include "cppdeclfromdef.h"
#include <Literals.h> //### remove
#include <QDebug> //###remove
#include <AST.h>
#include <ASTVisitor.h>
#include <CoreTypes.h>
#include <Names.h>
#include <Symbols.h>
#include <TranslationUnit.h>
#include <cplusplus/ASTPath.h>
#include <cplusplus/LookupContext.h>
#include <cplusplus/Overview.h>
#include <QtCore/QCoreApplication>
using
namespace
CPlusPlus
;
using
namespace
CppEditor
::
Internal
;
using
namespace
CppTools
;
using
CppEditor
::
CppRefactoringChanges
;
namespace
{
class
InsertionPointFinder
:
public
ASTVisitor
{
public:
InsertionPointFinder
(
Document
::
Ptr
doc
,
const
QString
&
className
)
:
ASTVisitor
(
doc
->
translationUnit
())
,
_doc
(
doc
)
,
_className
(
className
)
{}
void
operator
()(
int
*
line
,
int
*
column
)
{
if
(
!
line
&&
!
column
)
return
;
_line
=
0
;
_column
=
0
;
AST
*
ast
=
translationUnit
()
->
ast
();
accept
(
ast
);
if
(
line
)
*
line
=
_line
-
1
;
if
(
column
)
*
column
=
_column
-
1
;
}
protected:
using
ASTVisitor
::
visit
;
bool
visit
(
ClassSpecifierAST
*
ast
)
{
if
(
!
ast
->
symbol
||
_className
!=
QLatin1String
(
ast
->
symbol
->
identifier
()
->
chars
()))
return
true
;
unsigned
currentVisibility
=
(
tokenKind
(
ast
->
classkey_token
)
==
T_CLASS
)
?
T_PUBLIC
:
T_PRIVATE
;
unsigned
insertBefore
=
0
;
for
(
DeclarationListAST
*
iter
=
ast
->
member_specifier_list
;
iter
;
iter
=
iter
->
next
)
{
DeclarationAST
*
decl
=
iter
->
value
;
if
(
AccessDeclarationAST
*
xsDecl
=
decl
->
asAccessDeclaration
())
{
const
unsigned
token
=
xsDecl
->
access_specifier_token
;
const
int
kind
=
tokenKind
(
token
);
if
(
kind
==
T_PUBLIC
)
{
currentVisibility
=
T_PUBLIC
;
}
else
if
(
kind
==
T_PROTECTED
)
{
if
(
currentVisibility
==
T_PUBLIC
)
{
insertBefore
=
token
;
break
;
}
else
{
currentVisibility
=
T_PROTECTED
;
}
}
else
if
(
kind
==
T_PRIVATE
)
{
if
(
currentVisibility
==
T_PUBLIC
||
currentVisibility
==
T_PROTECTED
)
{
insertBefore
=
token
;
break
;
}
else
{
currentVisibility
=
T_PRIVATE
;
}
}
}
}
if
(
!
insertBefore
)
insertBefore
=
ast
->
rbrace_token
;
getTokenStartPosition
(
insertBefore
,
&
_line
,
&
_column
);
return
false
;
}
private:
Document
::
Ptr
_doc
;
QString
_className
;
unsigned
_line
;
unsigned
_column
;
};
QString
prettyMinimalType
(
const
FullySpecifiedType
&
ty
,
const
LookupContext
&
context
,
Scope
*
source
,
ClassOrNamespace
*
target
)
{
Overview
oo
;
if
(
const
NamedType
*
namedTy
=
ty
->
asNamedType
())
return
oo
.
prettyTypeWithName
(
ty
,
context
.
minimalName
(
namedTy
->
name
(),
source
,
target
),
context
.
control
().
data
());
else
return
oo
(
ty
);
}
}
// anonymous namespace
DeclFromDef
::
DeclFromDef
(
TextEditor
::
BaseTextEditor
*
editor
)
:
CppQuickFixOperation
(
editor
)
{}
QString
DeclFromDef
::
description
()
const
{
return
QCoreApplication
::
tr
(
"Create Declaration from Definition"
,
"DeclFromDef"
);
}
int
DeclFromDef
::
match
(
const
QList
<
CPlusPlus
::
AST
*>
&
path
)
{
m_targetFileName
.
clear
();
m_targetSymbolName
.
clear
();
m_decl
.
clear
();
FunctionDefinitionAST
*
funDef
=
0
;
int
idx
=
0
;
for
(;
idx
<
path
.
size
();
++
idx
)
{
AST
*
node
=
path
.
at
(
idx
);
if
(
FunctionDefinitionAST
*
candidate
=
node
->
asFunctionDefinition
())
if
(
!
funDef
)
funDef
=
candidate
;
else
if
(
node
->
asClassSpecifier
())
return
-
1
;
}
if
(
!
funDef
||
!
funDef
->
symbol
)
return
-
1
;
Function
*
method
=
funDef
->
symbol
;
LookupContext
context
(
document
(),
snapshot
());
if
(
ClassOrNamespace
*
targetBinding
=
context
.
lookupParent
(
method
))
{
foreach
(
Symbol
*
s
,
targetBinding
->
symbols
())
{
if
(
Class
*
clazz
=
s
->
asClass
())
{
m_targetFileName
=
QLatin1String
(
clazz
->
fileName
());
m_targetSymbolName
=
QLatin1String
(
clazz
->
identifier
()
->
chars
());
m_decl
=
generateDeclaration
(
method
,
targetBinding
);
return
idx
;
}
// ### TODO: support insertion into namespaces
}
}
return
-
1
;
}
void
DeclFromDef
::
createChanges
()
{
CppRefactoringChanges
*
changes
=
refactoringChanges
();
Document
::
Ptr
targetDoc
=
changes
->
document
(
m_targetFileName
);
InsertionPointFinder
findInsertionPoint
(
targetDoc
,
m_targetSymbolName
);
int
line
=
0
,
column
=
0
;
findInsertionPoint
(
&
line
,
&
column
);
int
targetPosition1
=
changes
->
positionInFile
(
m_targetFileName
,
line
,
column
);
int
targetPosition2
=
changes
->
positionInFile
(
m_targetFileName
,
line
+
1
,
0
)
-
1
;
Utils
::
ChangeSet
target
;
target
.
insert
(
targetPosition1
,
m_decl
);
changes
->
changeFile
(
m_targetFileName
,
target
);
changes
->
reindent
(
m_targetFileName
,
Utils
::
ChangeSet
::
Range
(
targetPosition1
,
targetPosition2
));
changes
->
openEditor
(
m_targetFileName
,
line
,
column
);
}
QString
DeclFromDef
::
generateDeclaration
(
Function
*
method
,
ClassOrNamespace
*
targetBinding
)
{
LookupContext
context
(
document
(),
snapshot
());
Overview
oo
;
QString
decl
;
decl
.
append
(
prettyMinimalType
(
method
->
returnType
(),
context
,
method
->
scope
(),
targetBinding
));
decl
.
append
(
QLatin1Char
(
' '
));
decl
.
append
(
QLatin1String
(
method
->
name
()
->
identifier
()
->
chars
()));
decl
.
append
(
QLatin1Char
(
'('
));
for
(
unsigned
argIdx
=
0
;
argIdx
<
method
->
argumentCount
();
++
argIdx
)
{
if
(
argIdx
>
0
)
decl
.
append
(
QLatin1String
(
", "
));
Argument
*
arg
=
method
->
argumentAt
(
argIdx
)
->
asArgument
();
decl
.
append
(
prettyMinimalType
(
arg
->
type
(),
context
,
method
->
members
(),
targetBinding
));
decl
.
append
(
QLatin1Char
(
' '
));
decl
.
append
(
oo
(
arg
->
name
()));
}
decl
.
append
(
QLatin1String
(
");
\n\n
"
));
return
decl
;
}
src/plugins/cppeditor/cppdeclfromdef.h
0 → 100644
View file @
9135c8cc
/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** Commercial Usage
**
** Licensees holding valid Qt Commercial licenses may use this file in
** accordance with the Qt Commercial License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Nokia.
**
** GNU Lesser General Public License Usage
**
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** If you are unsure which license is appropriate for your use, please
** contact the sales department at http://qt.nokia.com/contact.
**
**************************************************************************/
#ifndef CPPDECLFROMDEF_H
#define CPPDECLFROMDEF_H
#include "cppquickfix.h"
#include <CPlusPlusForwardDeclarations.h>
namespace
CPlusPlus
{
class
ClassOrNamespace
;
}
// namespace CPlusPlus
namespace
CppEditor
{
namespace
Internal
{
class
DeclFromDef
:
public
CppQuickFixOperation
{
public:
DeclFromDef
(
TextEditor
::
BaseTextEditor
*
editor
);
virtual
int
match
(
const
QList
<
CPlusPlus
::
AST
*>
&
path
);
virtual
QString
description
()
const
;
virtual
void
createChanges
();
protected:
virtual
QString
generateDeclaration
(
CPlusPlus
::
Function
*
method
,
CPlusPlus
::
ClassOrNamespace
*
targetBinding
);
private:
QString
m_targetFileName
;
QString
m_targetSymbolName
;
QString
m_decl
;
};
}
// namespace Internal
}
// namespace CppEditor
#endif // CPPDECLFROMDEF_H
src/plugins/cppeditor/cppeditor.pro
View file @
9135c8cc
...
...
@@ -19,7 +19,8 @@ HEADERS += cppplugin.h \
cpprefactoringchanges
.
h
\
cppcheckundefinedsymbols
.
h
\
cppsemanticinfo
.
h
\
cppoutline
.
h
cppoutline
.
h
\
cppdeclfromdef
.
h
SOURCES
+=
cppplugin
.
cpp
\
cppeditor
.
cpp
\
...
...
@@ -31,7 +32,8 @@ SOURCES += cppplugin.cpp \
cpprefactoringchanges
.
cpp
\
cppcheckundefinedsymbols
.
cpp
\
cppsemanticinfo
.
cpp
\
cppoutline
.
cpp
cppoutline
.
cpp
\
cppdeclfromdef
.
cpp
RESOURCES
+=
cppeditor
.
qrc
...
...
src/plugins/cppeditor/cppquickfix.cpp
View file @
9135c8cc
...
...
@@ -29,6 +29,7 @@
#include "cppquickfix.h"
#include "cppeditor.h"
#include "cppdeclfromdef.h"
#include <cplusplus/ASTPath.h>
#include <cplusplus/CppDocument.h>
...
...
@@ -1546,6 +1547,7 @@ QList<TextEditor::QuickFixOperation::Ptr> CppQuickFixFactory::quickFixOperations
QSharedPointer
<
ConvertNumericToOctal
>
convertNumericToOctal
(
new
ConvertNumericToOctal
(
editor
));
QSharedPointer
<
ConvertNumericToDecimal
>
convertNumericToDecimal
(
new
ConvertNumericToDecimal
(
editor
));
QSharedPointer
<
CompleteSwitchCaseStatement
>
completeSwitchCaseStatement
(
new
CompleteSwitchCaseStatement
(
editor
));
QSharedPointer
<
DeclFromDef
>
declFromDef
(
new
DeclFromDef
(
editor
));
quickFixOperations
.
append
(
rewriteLogicalAndOp
);
quickFixOperations
.
append
(
splitIfStatementOp
);
...
...
@@ -1561,6 +1563,7 @@ QList<TextEditor::QuickFixOperation::Ptr> CppQuickFixFactory::quickFixOperations
quickFixOperations
.
append
(
convertNumericToOctal
);
quickFixOperations
.
append
(
convertNumericToDecimal
);
quickFixOperations
.
append
(
completeSwitchCaseStatement
);
quickFixOperations
.
append
(
declFromDef
);
if
(
editor
->
mimeType
()
==
CppTools
::
Constants
::
OBJECTIVE_CPP_SOURCE_MIMETYPE
)
quickFixOperations
.
append
(
wrapCString
);
...
...
src/plugins/texteditor/refactoringchanges.cpp
View file @
9135c8cc
...
...
@@ -39,6 +39,11 @@
using
namespace
TextEditor
;
RefactoringChanges
::
RefactoringChanges
()
:
m_lineToShow
(
0
)
,
m_columnToShow
(
0
)
{}
RefactoringChanges
::~
RefactoringChanges
()
{}
...
...
@@ -149,12 +154,20 @@ QStringList RefactoringChanges::apply()
// ###
}
if
(
!
m_fileNameToShow
.
isEmpty
())
{
Core
::
EditorManager
*
editorManager
=
Core
::
EditorManager
::
instance
();
BaseTextEditor
*
editor
=
editorForFile
(
m_fileNameToShow
);
editorManager
->
activateEditor
(
editor
->
editableInterface
());
if
(
m_lineToShow
!=
-
1
)
editor
->
gotoLine
(
m_lineToShow
+
1
,
m_columnToShow
+
1
);
}
return
changed
.
toList
();
}
int
RefactoringChanges
::
positionInFile
(
const
QString
&
fileName
,
int
line
,
int
column
)
const
{
if
(
BaseTextEditor
*
editor
=
editorForFile
(
fileName
))
{
if
(
BaseTextEditor
*
editor
=
editorForFile
(
fileName
,
true
))
{
return
editor
->
document
()
->
findBlockByNumber
(
line
).
position
()
+
column
;
}
else
{
return
-
1
;
...
...
@@ -191,3 +204,10 @@ BaseTextEditor *RefactoringChanges::editorForNewFile(const QString &fileName)
f
.
close
();
return
editorForFile
(
fileName
,
true
);
}
void
RefactoringChanges
::
openEditor
(
const
QString
&
fileName
,
int
line
,
int
column
)
{
m_fileNameToShow
=
fileName
;
m_lineToShow
=
line
;
m_columnToShow
=
column
;
}
src/plugins/texteditor/refactoringchanges.h
View file @
9135c8cc
...
...
@@ -46,6 +46,7 @@ public:
typedef
Utils
::
ChangeSet
::
Range
Range
;
public:
RefactoringChanges
();
virtual
~
RefactoringChanges
();
void
createFile
(
const
QString
&
fileName
,
const
QString
&
contents
);
...
...
@@ -63,10 +64,16 @@ public:
bool
openIfClosed
=
false
);
static
BaseTextEditor
*
editorForNewFile
(
const
QString
&
fileName
);
/** line and column are zero-based */
void
openEditor
(
const
QString
&
fileName
,
int
line
,
int
column
);
private:
QMap
<
QString
,
QString
>
m_contentsByCreatedFile
;
QMap
<
QString
,
Utils
::
ChangeSet
>
m_changesByFile
;
QMap
<
QString
,
QList
<
Range
>
>
m_indentRangesByFile
;
QString
m_fileNameToShow
;
int
m_lineToShow
;
int
m_columnToShow
;
};
}
// namespace TextEditor
...
...
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