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
795ae72e
Commit
795ae72e
authored
Jul 08, 2010
by
con
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Quick fix for completing cases in enum based switch statements.
Reviewed-by: Roberto Raggi
parent
5751f4f1
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
159 additions
and
2 deletions
+159
-2
src/libs/cplusplus/TypeOfExpression.cpp
src/libs/cplusplus/TypeOfExpression.cpp
+11
-2
src/libs/cplusplus/TypeOfExpression.h
src/libs/cplusplus/TypeOfExpression.h
+16
-0
src/plugins/cppeditor/cppquickfix.cpp
src/plugins/cppeditor/cppquickfix.cpp
+132
-0
No files found.
src/libs/cplusplus/TypeOfExpression.cpp
View file @
795ae72e
...
...
@@ -79,11 +79,20 @@ QList<LookupItem> TypeOfExpression::operator()(const QString &expression,
Document
::
Ptr
expressionDoc
=
documentForExpression
(
code
);
expressionDoc
->
check
();
m_ast
=
extractExpressionAST
(
expressionDoc
);
return
this
->
operator
()(
extractExpressionAST
(
expressionDoc
),
expressionDoc
,
scope
);
}
QList
<
LookupItem
>
TypeOfExpression
::
operator
()(
ExpressionAST
*
expression
,
Document
::
Ptr
document
,
Scope
*
scope
)
{
m_ast
=
expression
;
m_scope
=
scope
;
m_lookupContext
=
LookupContext
(
expressionDoc
,
m_thisDocument
,
m_snapshot
);
m_lookupContext
=
LookupContext
(
document
,
m_thisDocument
,
m_snapshot
);
m_lookupContext
.
setBindings
(
m_bindings
);
ResolveExpression
resolve
(
m_lookupContext
);
...
...
src/libs/cplusplus/TypeOfExpression.h
View file @
795ae72e
...
...
@@ -82,6 +82,22 @@ public:
Scope
*
scope
,
PreprocessMode
mode
=
NoPreprocess
);
/**
* Returns a list of possible fully specified types associated with the
* given expression AST from the given document.
*
* NOTE: The fully specified types only stay valid for as long as this
* expression evaluator instance still exists, and no new call to evaluate
* has been made!
*
* @param expression The expression to evaluate.
* @param document The document in which the expression lives.
* @param scope The scope enclosing the expression.
*/
QList
<
LookupItem
>
operator
()(
ExpressionAST
*
expression
,
Document
::
Ptr
document
,
Scope
*
scope
);
QString
preprocess
(
const
QString
&
expression
)
const
;
/**
...
...
src/plugins/cppeditor/cppquickfix.cpp
View file @
795ae72e
...
...
@@ -34,6 +34,7 @@
#include <cplusplus/CppDocument.h>
#include <cplusplus/ResolveExpression.h>
#include <cplusplus/Overview.h>
#include <cplusplus/TypeOfExpression.h>
#include <TranslationUnit.h>
#include <ASTVisitor.h>
...
...
@@ -1217,6 +1218,135 @@ public:
};
/*
Adds missing case statements for "switch (enumVariable)"
*/
class
CompleteSwitchCaseStatement
:
public
CppQuickFixOperation
{
public:
CompleteSwitchCaseStatement
(
TextEditor
::
BaseTextEditor
*
editor
)
:
CppQuickFixOperation
(
editor
)
{}
virtual
QString
description
()
const
{
return
QApplication
::
translate
(
"CppTools::QuickFix"
,
"Complete Switch Statement"
);
}
virtual
int
match
(
const
QList
<
AST
*>
&
path
)
{
if
(
path
.
isEmpty
())
return
-
1
;
// nothing to do
// look for switch statement
for
(
int
depth
=
path
.
size
()
-
1
;
depth
>=
0
;
--
depth
)
{
AST
*
ast
=
path
.
at
(
depth
);
SwitchStatementAST
*
switchStatement
=
ast
->
asSwitchStatement
();
if
(
switchStatement
)
{
if
(
!
isCursorOn
(
switchStatement
->
switch_token
)
||
!
switchStatement
->
statement
)
return
-
1
;
compoundStatement
=
switchStatement
->
statement
->
asCompoundStatement
();
if
(
!
compoundStatement
)
// we ignore pathologic case "switch (t) case A: ;"
return
-
1
;
// look if the condition's type is an enum
if
(
Enum
*
e
=
conditionEnum
(
switchStatement
))
{
// check the possible enum values
values
.
clear
();
Overview
prettyPrint
;
for
(
unsigned
i
=
0
;
i
<
e
->
memberCount
();
++
i
)
{
if
(
Declaration
*
decl
=
e
->
memberAt
(
i
)
->
asDeclaration
())
{
values
<<
prettyPrint
(
decl
->
name
());
}
}
// Get the used values
CaseStatementCollector
caseValues
(
document
()
->
translationUnit
());
QStringList
usedValues
=
caseValues
(
switchStatement
);
// save the values that would be added
foreach
(
const
QString
&
usedValue
,
usedValues
)
values
.
removeAll
(
usedValue
);
if
(
values
.
isEmpty
())
return
-
1
;
return
depth
;
}
return
-
1
;
}
}
return
-
1
;
}
virtual
void
createChanges
()
{
ChangeSet
changes
;
int
start
=
endOf
(
compoundStatement
->
lbrace_token
);
changes
.
insert
(
start
,
QLatin1String
(
"
\n
case "
)
+
values
.
join
(
QLatin1String
(
":
\n
break;
\n
case "
))
+
QLatin1String
(
":
\n
break;"
));
refactoringChanges
()
->
changeFile
(
fileName
(),
changes
);
refactoringChanges
()
->
reindent
(
fileName
(),
range
(
compoundStatement
));
}
protected:
Enum
*
conditionEnum
(
SwitchStatementAST
*
statement
)
{
Block
*
block
=
statement
->
symbol
;
Scope
*
scope
=
document
()
->
scopeAt
(
block
->
line
(),
block
->
column
());
TypeOfExpression
typeOfExpression
;
typeOfExpression
.
init
(
document
(),
snapshot
());
const
QList
<
LookupItem
>
results
=
typeOfExpression
(
statement
->
condition
,
document
(),
scope
);
foreach
(
LookupItem
result
,
results
)
{
FullySpecifiedType
fst
=
result
.
type
();
if
(
Enum
*
e
=
result
.
declaration
()
->
type
()
->
asEnumType
())
return
e
;
if
(
NamedType
*
namedType
=
fst
->
asNamedType
())
{
QList
<
Symbol
*>
candidates
=
typeOfExpression
.
context
().
lookup
(
namedType
->
name
(),
scope
);
foreach
(
Symbol
*
candidate
,
candidates
)
{
if
(
Enum
*
e
=
candidate
->
asEnum
())
{
return
e
;
}
}
}
}
return
0
;
}
class
CaseStatementCollector
:
public
ASTVisitor
{
public:
CaseStatementCollector
(
TranslationUnit
*
unit
)
:
ASTVisitor
(
unit
)
{}
QStringList
operator
()(
AST
*
ast
)
{
values
.
clear
();
foundCaseStatementLevel
=
false
;
accept
(
ast
);
return
values
;
}
bool
preVisit
(
AST
*
ast
)
{
if
(
CaseStatementAST
*
cs
=
ast
->
asCaseStatement
())
{
foundCaseStatementLevel
=
true
;
if
(
SimpleNameAST
*
sm
=
cs
->
expression
->
asSimpleName
())
{
Overview
prettyPrint
;
values
<<
prettyPrint
(
sm
->
name
);
}
return
true
;
}
else
if
(
foundCaseStatementLevel
)
{
return
false
;
}
return
true
;
}
bool
foundCaseStatementLevel
;
QStringList
values
;
};
protected:
CompoundStatementAST
*
compoundStatement
;
QStringList
values
;
};
}
// end of anonymous namespace
...
...
@@ -1415,6 +1545,7 @@ QList<TextEditor::QuickFixOperation::Ptr> CppQuickFixFactory::quickFixOperations
QSharedPointer
<
ConvertNumericToHex
>
convertNumericToHex
(
new
ConvertNumericToHex
(
editor
));
QSharedPointer
<
ConvertNumericToOctal
>
convertNumericToOctal
(
new
ConvertNumericToOctal
(
editor
));
QSharedPointer
<
ConvertNumericToDecimal
>
convertNumericToDecimal
(
new
ConvertNumericToDecimal
(
editor
));
QSharedPointer
<
CompleteSwitchCaseStatement
>
completeSwitchCaseStatement
(
new
CompleteSwitchCaseStatement
(
editor
));
quickFixOperations
.
append
(
rewriteLogicalAndOp
);
quickFixOperations
.
append
(
splitIfStatementOp
);
...
...
@@ -1429,6 +1560,7 @@ QList<TextEditor::QuickFixOperation::Ptr> CppQuickFixFactory::quickFixOperations
quickFixOperations
.
append
(
convertNumericToHex
);
quickFixOperations
.
append
(
convertNumericToOctal
);
quickFixOperations
.
append
(
convertNumericToDecimal
);
quickFixOperations
.
append
(
completeSwitchCaseStatement
);
if
(
editor
->
mimeType
()
==
CppTools
::
Constants
::
OBJECTIVE_CPP_SOURCE_MIMETYPE
)
quickFixOperations
.
append
(
wrapCString
);
...
...
Write
Preview
Markdown
is supported
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