mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-04-22 22:22:11 +02:00
Bug 535256: Rewrite removes attributes, key and base from C++ enum
Fix and tests. Change-Id: I1f5519f833563378d87b3c932b754e29c3e32b06 Signed-off-by: Hansruedi Patzen <hansruedi.patzen@hsr.ch> Signed-off-by: Thomas Corbat <tcorbat@hsr.ch>
This commit is contained in:
parent
4c66f7c8f3
commit
bc4aa4597d
10 changed files with 178 additions and 10 deletions
|
@ -55,6 +55,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier;
|
|||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTConstructorChainInitializer;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTConstructorInitializer;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTDeclarator;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTEnumerationSpecifier;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTForStatement;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionDeclarator;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionDefinition;
|
||||
|
@ -1225,4 +1226,18 @@ public class ReplaceTests extends ChangeGeneratorTest {
|
|||
public void testCopyReplaceAttribute_Bug535275() throws Exception {
|
||||
compareCopyResult(new CopyReplaceVisitor(this, ICPPASTFunctionDeclarator.class::isInstance));
|
||||
}
|
||||
|
||||
//enum [[foo]] X : int [[bar]] {
|
||||
//};
|
||||
public void testEnumReplacementRetainsAttributes_Bug535256_1() throws Exception {
|
||||
compareCopyResult(new CopyReplaceVisitor(this, ICPPASTEnumerationSpecifier.class::isInstance));
|
||||
}
|
||||
|
||||
//enum class EC {
|
||||
//};
|
||||
//enum struct ES {
|
||||
//};
|
||||
public void testScopedEnumReplacementRetains_Bug535256_2() throws Exception {
|
||||
compareCopyResult(new CopyReplaceVisitor(this, ICPPASTEnumerationSpecifier.class::isInstance));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -194,3 +194,23 @@ namespace [[foo]] FOO __attribute__((__visibility__("default")))
|
|||
|
||||
|
||||
}
|
||||
|
||||
//!Attributed anonymous enum declaration
|
||||
//%CPP
|
||||
enum [[foo]] { };
|
||||
|
||||
//!Attributed named enum declaration
|
||||
//%CPP
|
||||
enum [[foo]] X{ };
|
||||
|
||||
//!Attributed anonymous enum with attributed base specifier
|
||||
//%CPP
|
||||
enum [[foo]] : int [[bar]] { };
|
||||
|
||||
//!Attributed scoped enum declaration with keyword struct
|
||||
//%CPP
|
||||
enum struct [[foo]] X{ };
|
||||
|
||||
//!Attributed scoped enum declaration with keyword class
|
||||
//%CPP
|
||||
enum class [[foo]] X{ };
|
||||
|
|
|
@ -24,6 +24,15 @@ public interface ICPPASTEnumerationSpecifier extends IASTEnumerationSpecifier, I
|
|||
public static final ASTNodeProperty BASE_TYPE = new ASTNodeProperty(
|
||||
"ICPPASTEnumerationSpecifier.BASE_TYPE [ICPPASTDeclSpecifier]"); //$NON-NLS-1$
|
||||
|
||||
/**
|
||||
* @since 6.5
|
||||
*/
|
||||
public enum ScopeStyle {
|
||||
CLASS,
|
||||
STRUCT,
|
||||
NONE
|
||||
}
|
||||
|
||||
@Override
|
||||
public ICPPASTEnumerationSpecifier copy();
|
||||
|
||||
|
@ -35,8 +44,23 @@ public interface ICPPASTEnumerationSpecifier extends IASTEnumerationSpecifier, I
|
|||
|
||||
/**
|
||||
* Not allowed on frozen AST.
|
||||
* @deprecated Use setScopeToken instead
|
||||
* If {@code isScoped == true} is passed, the {@code ScopeToken.CLASS} scope token is assumed.
|
||||
*/
|
||||
@Deprecated
|
||||
public void setIsScoped(boolean isScoped);
|
||||
|
||||
/**
|
||||
* Not allowed on frozen AST.
|
||||
* @since 6.5
|
||||
*/
|
||||
public void setScopeStyle(ScopeStyle scopeStyle);
|
||||
|
||||
/**
|
||||
* @since 6.5
|
||||
*/
|
||||
public ScopeStyle getScopeStyle();
|
||||
|
||||
|
||||
/**
|
||||
* An enum is scoped if it uses the enumeration head {@code enum class} or {@code enum struct}.
|
||||
|
|
|
@ -30,6 +30,7 @@ import org.eclipse.cdt.core.dom.ast.IASTToken;
|
|||
import org.eclipse.cdt.core.dom.ast.IASTTypeId;
|
||||
import org.eclipse.cdt.core.dom.ast.INodeFactory;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTEnumerationSpecifier.ScopeStyle;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPUnaryTypeTransformation.Operator;
|
||||
import org.eclipse.cdt.core.dom.ast.gnu.cpp.IGPPASTArrayRangeDesignator;
|
||||
import org.eclipse.cdt.core.dom.parser.cpp.ICPPASTAttributeSpecifier;
|
||||
|
@ -158,9 +159,17 @@ public interface ICPPNodeFactory extends INodeFactory {
|
|||
|
||||
/**
|
||||
* @since 5.2
|
||||
* @deprecated Use {@code newEnumerationSpecifier(ScopeToken, IASTName, ICPPASTDeclSpecifier)} instead.
|
||||
* If {@code isScoped == true} is passed {@code ScopeToken.CLASS} is assumed.
|
||||
*/
|
||||
@Deprecated
|
||||
public ICPPASTEnumerationSpecifier newEnumerationSpecifier(boolean isScoped, IASTName name, ICPPASTDeclSpecifier baseType);
|
||||
|
||||
/**
|
||||
* @since 6.5
|
||||
*/
|
||||
public ICPPASTEnumerationSpecifier newEnumerationSpecifier(ScopeStyle scopeStyle, IASTName name, ICPPASTDeclSpecifier baseType);
|
||||
|
||||
public ICPPASTExplicitTemplateInstantiation newExplicitTemplateInstantiation(IASTDeclaration declaration);
|
||||
|
||||
@Override
|
||||
|
|
|
@ -26,7 +26,7 @@ import org.eclipse.cdt.internal.core.dom.parser.IASTInternalEnumerationSpecifier
|
|||
*/
|
||||
public class CPPASTEnumerationSpecifier extends CPPASTBaseDeclSpecifier
|
||||
implements IASTInternalEnumerationSpecifier, ICPPASTEnumerationSpecifier {
|
||||
private boolean fIsScoped;
|
||||
private ScopeStyle fScopeStyle;
|
||||
private boolean fIsOpaque;
|
||||
private IASTName fName;
|
||||
private ICPPASTDeclSpecifier fBaseType;
|
||||
|
@ -40,12 +40,18 @@ public class CPPASTEnumerationSpecifier extends CPPASTBaseDeclSpecifier
|
|||
public CPPASTEnumerationSpecifier() {
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public CPPASTEnumerationSpecifier(boolean isScoped, IASTName name, ICPPASTDeclSpecifier baseType) {
|
||||
fIsScoped= isScoped;
|
||||
this(isScoped ? ScopeStyle.CLASS : ScopeStyle.NONE, name, baseType);
|
||||
}
|
||||
|
||||
public CPPASTEnumerationSpecifier(ScopeStyle scopeStyle, IASTName name, ICPPASTDeclSpecifier baseType) {
|
||||
setScopeStyle(scopeStyle);
|
||||
setName(name);
|
||||
setBaseType(baseType);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public CPPASTEnumerationSpecifier copy() {
|
||||
return copy(CopyStyle.withoutLocations);
|
||||
|
@ -53,7 +59,7 @@ public class CPPASTEnumerationSpecifier extends CPPASTBaseDeclSpecifier
|
|||
|
||||
@Override
|
||||
public CPPASTEnumerationSpecifier copy(CopyStyle style) {
|
||||
CPPASTEnumerationSpecifier copy = new CPPASTEnumerationSpecifier(fIsScoped,
|
||||
CPPASTEnumerationSpecifier copy = new CPPASTEnumerationSpecifier(fScopeStyle,
|
||||
fName == null ? null : fName.copy(style),
|
||||
fBaseType == null ? null : fBaseType.copy(style));
|
||||
copy.fIsOpaque = fIsOpaque;
|
||||
|
@ -154,14 +160,25 @@ public class CPPASTEnumerationSpecifier extends CPPASTBaseDeclSpecifier
|
|||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public void setIsScoped(boolean isScoped) {
|
||||
setScopeStyle(isScoped ? ScopeStyle.CLASS : ScopeStyle.NONE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setScopeStyle(ScopeStyle scopeStyle) {
|
||||
assertNotFrozen();
|
||||
fIsScoped= isScoped;
|
||||
fScopeStyle = scopeStyle;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ScopeStyle getScopeStyle() {
|
||||
return fScopeStyle;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isScoped() {
|
||||
return fIsScoped;
|
||||
return fScopeStyle != ScopeStyle.NONE;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -78,6 +78,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTDeleteExpression;
|
|||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTDesignatedInitializer;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTElaboratedTypeSpecifier;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTEnumerationSpecifier;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTEnumerationSpecifier.ScopeStyle;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTExplicitTemplateInstantiation;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTExpression;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTExpressionList;
|
||||
|
@ -381,14 +382,21 @@ public class CPPNodeFactory extends NodeFactory implements ICPPNodeFactory {
|
|||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public ICPPASTEnumerationSpecifier newEnumerationSpecifier(boolean isScoped, IASTName name,
|
||||
ICPPASTDeclSpecifier baseType) {
|
||||
return new CPPASTEnumerationSpecifier(isScoped, name, baseType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ICPPASTEnumerationSpecifier newEnumerationSpecifier(ScopeStyle scopeStyle, IASTName name,
|
||||
ICPPASTDeclSpecifier baseType) {
|
||||
return new CPPASTEnumerationSpecifier(scopeStyle, name, baseType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ICPPASTEnumerationSpecifier newEnumerationSpecifier(IASTName name) {
|
||||
return new CPPASTEnumerationSpecifier(false, name, null);
|
||||
return new CPPASTEnumerationSpecifier(ScopeStyle.NONE, name, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -95,6 +95,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTDesignatedInitializer;
|
|||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTDesignator;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTElaboratedTypeSpecifier;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTEnumerationSpecifier;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTEnumerationSpecifier.ScopeStyle;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTExplicitTemplateInstantiation;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTExpression;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFieldDeclarator;
|
||||
|
@ -3561,7 +3562,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
|
|||
result= buildSimpleDeclSpec(storageClass, simpleType, options, isLong, typeofExpression, offset, endOffset);
|
||||
}
|
||||
addAttributeSpecifiers(attributes, result);
|
||||
attributesEndOffset(endOffset, attributes);
|
||||
endOffset = attributesEndOffset(endOffset, attributes);
|
||||
setRange(result, offset, endOffset);
|
||||
} catch (BacktrackException e) {
|
||||
if (returnToken != null) {
|
||||
|
@ -3628,6 +3629,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
|
|||
final int offset= consume(IToken.t_enum).getOffset();
|
||||
int endOffset= 0;
|
||||
boolean isScoped= false;
|
||||
ScopeStyle scopeStyle = ScopeStyle.NONE;
|
||||
IASTName name= null;
|
||||
ICPPASTDeclSpecifier baseType= null;
|
||||
List<IASTAttributeSpecifier> attributes = null;
|
||||
|
@ -3635,7 +3637,8 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
|
|||
try {
|
||||
int lt1= LT(1);
|
||||
if (lt1 == IToken.t_class || lt1 == IToken.t_struct) {
|
||||
isScoped= true;
|
||||
scopeStyle = (lt1 == IToken.t_class) ? ScopeStyle.CLASS : ScopeStyle.STRUCT;
|
||||
isScoped = true;
|
||||
consume();
|
||||
}
|
||||
// if __attribute__ or __declspec occurs after struct/union/class and before the identifier
|
||||
|
@ -3676,7 +3679,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
|
|||
name= getNodeFactory().newName();
|
||||
}
|
||||
|
||||
final ICPPASTEnumerationSpecifier result= getNodeFactory().newEnumerationSpecifier(isScoped, name, baseType);
|
||||
final ICPPASTEnumerationSpecifier result= getNodeFactory().newEnumerationSpecifier(scopeStyle, name, baseType);
|
||||
result.setIsOpaque(isOpaque);
|
||||
if (lt1 == IToken.tLBRACE) {
|
||||
endOffset= enumBody(result);
|
||||
|
|
|
@ -34,6 +34,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier;
|
|||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTDeclSpecifier;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTElaboratedTypeSpecifier;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTEnumerationSpecifier;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNamedTypeSpecifier;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTSimpleDeclSpecifier;
|
||||
import org.eclipse.cdt.core.parser.GCCKeywords;
|
||||
|
@ -225,8 +226,32 @@ public class DeclSpecWriter extends NodeWriter {
|
|||
|
||||
private void writeEnumSpec(IASTEnumerationSpecifier enumSpec) {
|
||||
scribe.printStringSpace(Keywords.ENUM);
|
||||
writeAttributes(enumSpec, EnumSet.of(SpaceLocation.AFTER));
|
||||
boolean isCppEnum = enumSpec instanceof ICPPASTEnumerationSpecifier;
|
||||
if (isCppEnum) {
|
||||
ICPPASTEnumerationSpecifier cppEnumSpec = (ICPPASTEnumerationSpecifier) enumSpec;
|
||||
if (cppEnumSpec.isScoped()) {
|
||||
switch (cppEnumSpec.getScopeStyle()) {
|
||||
case CLASS:
|
||||
scribe.printStringSpace(Keywords.CLASS);
|
||||
break;
|
||||
case STRUCT:
|
||||
scribe.printStringSpace(Keywords.STRUCT);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
writeAttributes(cppEnumSpec, EnumSet.of(SpaceLocation.AFTER));
|
||||
}
|
||||
enumSpec.getName().accept(visitor);
|
||||
if (isCppEnum) {
|
||||
ICPPASTDeclSpecifier baseType = ((ICPPASTEnumerationSpecifier) enumSpec).getBaseType();
|
||||
if (baseType != null) {
|
||||
scribe.print(SPACE_COLON_SPACE);
|
||||
writeDelcSpec(baseType);
|
||||
scribe.printSpace();
|
||||
}
|
||||
}
|
||||
scribe.print('{');
|
||||
scribe.printSpace();
|
||||
IASTEnumerator[] enums = enumSpec.getEnumerators();
|
||||
|
|
|
@ -114,11 +114,13 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier;
|
|||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTConstructorChainInitializer;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTConstructorInitializer;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTDeclSpecifier;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTDecltypeSpecifier;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTDeleteExpression;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTDesignatedInitializer;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTDesignator;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTElaboratedTypeSpecifier;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTEnumerationSpecifier;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTExplicitTemplateInstantiation;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFieldReference;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTForStatement;
|
||||
|
@ -2059,6 +2061,19 @@ public class CodeFormatterVisitor extends ASTVisitor implements ICPPASTVisitor,
|
|||
name.accept(this);
|
||||
}
|
||||
|
||||
ICPPASTEnumerationSpecifier cppNode = null;
|
||||
if (node instanceof ICPPASTEnumerationSpecifier) {
|
||||
cppNode = (ICPPASTEnumerationSpecifier) node;
|
||||
formatLeadingAttributes(cppNode);
|
||||
ICPPASTDeclSpecifier baseType = cppNode.getBaseType();
|
||||
if (baseType != null) {
|
||||
scribe.space();
|
||||
scribe.printNextToken(Token.tCOLON);
|
||||
scribe.space();
|
||||
baseType.accept(this);
|
||||
}
|
||||
}
|
||||
|
||||
formatLeftCurlyBrace(line, preferences.brace_position_for_type_declaration);
|
||||
formatOpeningBrace(preferences.brace_position_for_type_declaration, preferences.insert_space_before_opening_brace_in_type_declaration);
|
||||
final int braceIndent= scribe.numberOfIndentations;
|
||||
|
|
|
@ -3538,4 +3538,36 @@ public class CodeFormatterTest extends BaseUITestCase {
|
|||
public void testAttributedNamesapces_Bug535274() throws Exception {
|
||||
assertFormatterResult();
|
||||
}
|
||||
|
||||
//enum[[foo]]{};
|
||||
|
||||
//enum [[foo]] {
|
||||
//};
|
||||
public void testAttributedAnonymousEnumDeclaration_Bug535256_1() throws Exception {
|
||||
assertFormatterResult();
|
||||
}
|
||||
|
||||
//enum[[foo]] X{};
|
||||
|
||||
//enum [[foo]] X {
|
||||
//};
|
||||
public void testAttributedNamedEnumDeclaration_Bug535256_2() throws Exception {
|
||||
assertFormatterResult();
|
||||
}
|
||||
|
||||
//enum[[foo]]:int [[bar]]{};
|
||||
|
||||
//enum [[foo]] : int [[bar]] {
|
||||
//};
|
||||
public void testAttributedNamedEnumDeclarationWithAttributedBaseSpecifier_Bug535256_3() throws Exception {
|
||||
assertFormatterResult();
|
||||
}
|
||||
|
||||
//enum struct [[foo]] X{};
|
||||
|
||||
//enum struct [[foo]] X {
|
||||
//};
|
||||
public void testAttributedNamedScopedEnumDeclaration_Bug535256_4() throws Exception {
|
||||
assertFormatterResult();
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue