diff options
author | Felix Morgner | 2016-07-15 11:55:07 +0000 |
---|---|---|
committer | Thomas Corbat | 2017-05-15 06:59:54 +0000 |
commit | ca1ab7f52dc9174ca42660d5acbe3b634de7ee9e (patch) | |
tree | 0e15589348be87761c1a18bc326faaa953a324af | |
parent | 619da2a170183d4fb50272f39407365a8bb7a4b2 (diff) | |
download | org.eclipse.cdt-ca1ab7f52dc9174ca42660d5acbe3b634de7ee9e.tar.gz org.eclipse.cdt-ca1ab7f52dc9174ca42660d5acbe3b634de7ee9e.tar.xz org.eclipse.cdt-ca1ab7f52dc9174ca42660d5acbe3b634de7ee9e.zip |
Bug 491957. Preferences & save action for choosing const alignment
Conflicts:
core/org.eclipse.cdt.core/META-INF/MANIFEST.MF
core/org.eclipse.cdt.core/pom.xml
core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/TextTestSuite.java
core/org.eclipse.cdt.ui/pom.xml
Change-Id: I061fa28d2e0b37f6d00232ad619f23b892e13ce6
Signed-off-by: Mario Meili <mmeili@hsr.ch>
Signed-off-by: Benny Gaechter <benny.gaechter@hsr.ch>
Signed-off-by: Felix Morgner <fmorgner@hsr.ch>
39 files changed, 821 insertions, 25 deletions
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/astwriter/ASTWriter.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/astwriter/ASTWriter.java index 155547e9f99..d5fa3929bc4 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/astwriter/ASTWriter.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/astwriter/ASTWriter.java @@ -73,7 +73,7 @@ public class ASTWriter { */ public String write(IASTNode rootNode, NodeCommentMap commentMap) throws ProblemRuntimeException { ChangeGeneratorWriterVisitor writer = new ChangeGeneratorWriterVisitor( - modificationStore, null, commentMap); + modificationStore, null, commentMap, ConstPlacement.placeConstRight(rootNode)); if (rootNode != null) { rootNode.accept(writer); } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/astwriter/ASTWriterVisitor.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/astwriter/ASTWriterVisitor.java index 7c4585fb742..b4c65fdbaf4 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/astwriter/ASTWriterVisitor.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/astwriter/ASTWriterVisitor.java @@ -37,6 +37,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTDecltypeSpecifier; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNamespaceDefinition; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateParameter; import org.eclipse.cdt.core.dom.ast.gnu.IGNUASTCompoundStatementExpression; +import org.eclipse.cdt.core.model.ITranslationUnit; import org.eclipse.cdt.core.parser.Keywords; import org.eclipse.cdt.internal.core.dom.rewrite.ASTLiteralNode; import org.eclipse.cdt.internal.core.dom.rewrite.commenthandler.NodeCommentMap; @@ -93,6 +94,15 @@ public class ASTWriterVisitor extends ASTVisitor { this(new NodeCommentMap()); } + /** + * Creates a writer with an empty comment map that uses const placement + * properties of the project associated with the provided translation unit. + */ + public ASTWriterVisitor(ITranslationUnit tu) { + this(); + configureForTU(tu); + } + public ASTWriterVisitor(NodeCommentMap commentMap) { super(); init(commentMap); @@ -114,6 +124,11 @@ public class ASTWriterVisitor extends ASTVisitor { attributeWriter = new AttributeWriter(scribe, this, commentMap); } + public void configureForTU(ITranslationUnit tu) { + boolean placeConstRight = ConstPlacement.placeConstRight(tu); + declSpecWriter.setPlaceConstRight(placeConstRight); + } + @Override public String toString() { return scribe.toString(); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/astwriter/ConstPlacement.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/astwriter/ConstPlacement.java new file mode 100644 index 00000000000..9678edc0edc --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/astwriter/ConstPlacement.java @@ -0,0 +1,47 @@ +/******************************************************************************* + * Copyright (c) 2017 Institute for Software, HSR Hochschule fuer Technik + * Rapperswil, University of applied sciences and others + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + *******************************************************************************/ +package org.eclipse.cdt.internal.core.dom.rewrite.astwriter; + +import org.eclipse.cdt.core.CCorePreferenceConstants; +import org.eclipse.cdt.core.dom.ast.IASTNode; +import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit; +import org.eclipse.cdt.core.model.ICProject; +import org.eclipse.cdt.core.model.ITranslationUnit; +import org.eclipse.core.resources.IProject; + +public class ConstPlacement { + public static boolean placeConstRight(IASTNode node) { + if (node == null) { + return false; + } + IASTTranslationUnit translationUnit = node.getTranslationUnit(); + if (translationUnit == null) { + return false; + } + ITranslationUnit originatingTU = translationUnit.getOriginatingTranslationUnit(); + return placeConstRight(originatingTU); + } + + public static boolean placeConstRight(ITranslationUnit tu) { + IProject project = null; + if (tu != null) { + ICProject cProject = tu.getCProject(); + if (cProject != null) { + project = cProject.getProject(); + } + } + return placeConstRight(project); + } + + public static boolean placeConstRight(IProject project) { + return CCorePreferenceConstants.getPreference( + CCorePreferenceConstants.PLACE_CONST_RIGHT_OF_TYPE, project, + CCorePreferenceConstants.DEFAULT_PLACE_CONST_RIGHT_OF_TYPE); + } +} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/astwriter/DeclSpecWriter.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/astwriter/DeclSpecWriter.java index ba4e8aa09e4..a369a22f8d9 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/astwriter/DeclSpecWriter.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/astwriter/DeclSpecWriter.java @@ -50,19 +50,27 @@ import org.eclipse.cdt.internal.core.dom.rewrite.commenthandler.NodeCommentMap; * @author Emanuel Graf IFS */ public class DeclSpecWriter extends NodeWriter { + private boolean constRight = false; public DeclSpecWriter(Scribe scribe, ASTWriterVisitor visitor, NodeCommentMap commentMap) { super(scribe, visitor, commentMap); } + public void setPlaceConstRight(boolean placeConstRight) { + constRight = placeConstRight; + } + protected void writeDelcSpec(IASTDeclSpecifier declSpec) { - // Write general DelcSpec Keywords - writeDeclSpec(declSpec); + writeDeclSpec(declSpec, !constRight); if (declSpec instanceof ICPPASTDeclSpecifier) { writeCPPDeclSpec((ICPPASTDeclSpecifier) declSpec); } else if (declSpec instanceof ICASTDeclSpecifier) { writeCDeclSpec((ICASTDeclSpecifier) declSpec); } + if(constRight && declSpec.isConst()) { + scribe.printSpace(); + scribe.printStringSpace(Keywords.CONST); + } } private String getCPPSimpleDecSpecifier(ICPPASTSimpleDeclSpecifier simpDeclSpec) { @@ -343,7 +351,7 @@ public class DeclSpecWriter extends NodeWriter { } } - private void writeDeclSpec(IASTDeclSpecifier declSpec) { + private void writeDeclSpec(IASTDeclSpecifier declSpec, boolean constEnabled) { if (declSpec.isInline()) { scribe.printStringSpace(Keywords.INLINE); } @@ -364,7 +372,7 @@ public class DeclSpecWriter extends NodeWriter { scribe.printStringSpace(Keywords.REGISTER); break; } - if (declSpec.isConst()) { + if (declSpec.isConst() && constEnabled) { scribe.printStringSpace(Keywords.CONST); } if (declSpec.isVolatile()) { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/changegenerator/ChangeGenerator.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/changegenerator/ChangeGenerator.java index 360f9e1609b..b80ea9fef4b 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/changegenerator/ChangeGenerator.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/changegenerator/ChangeGenerator.java @@ -51,6 +51,7 @@ import org.eclipse.cdt.internal.core.dom.rewrite.ASTModificationMap; import org.eclipse.cdt.internal.core.dom.rewrite.ASTModificationStore; import org.eclipse.cdt.internal.core.dom.rewrite.ASTRewriteAnalyzer; import org.eclipse.cdt.internal.core.dom.rewrite.astwriter.ASTWriter; +import org.eclipse.cdt.internal.core.dom.rewrite.astwriter.ConstPlacement; import org.eclipse.cdt.internal.core.dom.rewrite.astwriter.ContainerNode; import org.eclipse.cdt.internal.core.dom.rewrite.astwriter.ProblemRuntimeException; import org.eclipse.cdt.internal.core.dom.rewrite.commenthandler.NodeCommentMap; @@ -340,8 +341,7 @@ public class ChangeGenerator extends ASTVisitor { List<ASTModification> modifications = getModifications(anchorNode, ModificationKind.INSERT_BEFORE); if (modifications.isEmpty()) return; - ChangeGeneratorWriterVisitor writer = - new ChangeGeneratorWriterVisitor(modificationStore, commentMap); + ChangeGeneratorWriterVisitor writer = createChangeWriterForNode(anchorNode); IASTNode newNode = null; for (ASTModification modification : modifications) { boolean first = newNode == null; @@ -384,8 +384,7 @@ public class ChangeGenerator extends ASTVisitor { private void handleReplace(IASTNode node) { List<ASTModification> modifications = getModifications(node, ModificationKind.REPLACE); String source = node.getTranslationUnit().getRawSignature(); - ChangeGeneratorWriterVisitor writer = - new ChangeGeneratorWriterVisitor(modificationStore, commentMap); + ChangeGeneratorWriterVisitor writer = createChangeWriterForNode(node); IASTFileLocation fileLocation = node.getFileLocation(); addToRootEdit(node); if (modifications.size() == 1 && modifications.get(0).getNewNode() == null) { @@ -443,8 +442,7 @@ public class ChangeGenerator extends ASTVisitor { List<ASTModification> modifications = getModifications(node, ModificationKind.APPEND_CHILD); if (modifications.isEmpty()) return; - ChangeGeneratorWriterVisitor writer = - new ChangeGeneratorWriterVisitor(modificationStore, commentMap); + ChangeGeneratorWriterVisitor writer = createChangeWriterForNode(node); ReplaceEdit anchor = getAppendAnchor(node); Assert.isNotNull(anchor); IASTNode precedingNode = getLastNodeBeforeAppendPoint(node); @@ -491,8 +489,7 @@ public class ChangeGenerator extends ASTVisitor { int endOffset = skipTrailingBlankLines(source, offset); addToRootEdit(node); - ChangeGeneratorWriterVisitor writer = - new ChangeGeneratorWriterVisitor(modificationStore, commentMap); + ChangeGeneratorWriterVisitor writer = createChangeWriterForNode(node); IASTNode newNode = null; for (ASTModification modification : modifications) { boolean first = newNode == null; @@ -525,6 +522,10 @@ public class ChangeGenerator extends ASTVisitor { addChildEdit(new DeleteEdit(offset, endOffset - offset)); } + private ChangeGeneratorWriterVisitor createChangeWriterForNode(IASTNode node) { + return new ChangeGeneratorWriterVisitor(modificationStore, commentMap, ConstPlacement.placeConstRight(node)); + } + /** * Returns the list of nodes the given node is part of, for example function parameters if * the node is a parameter. diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/changegenerator/ChangeGeneratorWriterVisitor.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/changegenerator/ChangeGeneratorWriterVisitor.java index ff14bb832c5..8a5f18b887a 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/changegenerator/ChangeGeneratorWriterVisitor.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/changegenerator/ChangeGeneratorWriterVisitor.java @@ -50,7 +50,7 @@ public class ChangeGeneratorWriterVisitor extends ASTWriterVisitor { private ModificationScopeStack stack; public ChangeGeneratorWriterVisitor(ASTVisitor delegateVisitor, - ASTModificationStore modificationStore, String fileScope, NodeCommentMap commentMap) { + ASTModificationStore modificationStore, String fileScope, NodeCommentMap commentMap, boolean placeConstRight) { super(commentMap); this.modificationStore = modificationStore; @@ -76,11 +76,21 @@ public class ChangeGeneratorWriterVisitor extends ASTWriterVisitor { } public ChangeGeneratorWriterVisitor(ASTModificationStore modStore, NodeCommentMap nodeMap) { - this(modStore, null, nodeMap); + this(modStore, null, nodeMap, false); + } + + public ChangeGeneratorWriterVisitor(ASTModificationStore modStore, NodeCommentMap nodeMap, + boolean placeConstRight) { + this(modStore, null, nodeMap, placeConstRight); } public ChangeGeneratorWriterVisitor(ASTModificationStore modStore, String fileScope, NodeCommentMap commentMap) { + this(modStore, fileScope, commentMap, false); + } + + public ChangeGeneratorWriterVisitor(ASTModificationStore modStore, String fileScope, + NodeCommentMap commentMap, boolean placeConstRight) { super(commentMap); this.modificationStore = modStore; this.fileScope = fileScope; @@ -89,7 +99,7 @@ public class ChangeGeneratorWriterVisitor extends ASTWriterVisitor { declaratorWriter = new ModifiedASTDeclaratorWriter(scribe, this, stack, commentMap); expWriter = new ModifiedASTExpressionWriter(scribe, this, macroHandler, stack, commentMap); statementWriter = new ModifiedASTStatementWriter(scribe, this, stack, commentMap); - declSpecWriter = new ModifiedASTDeclSpecWriter(scribe, this, stack, commentMap); + declSpecWriter = new ModifiedASTDeclSpecWriter(scribe, this, stack, commentMap, placeConstRight); declarationWriter = new ModifiedASTDeclarationWriter(scribe, this, stack, commentMap); } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/changegenerator/ModifiedASTDeclSpecWriter.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/changegenerator/ModifiedASTDeclSpecWriter.java index cd591419002..af0a7fc77ef 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/changegenerator/ModifiedASTDeclSpecWriter.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/changegenerator/ModifiedASTDeclSpecWriter.java @@ -22,8 +22,9 @@ public class ModifiedASTDeclSpecWriter extends DeclSpecWriter { private final ASTModificationHelper modificationHelper; public ModifiedASTDeclSpecWriter(Scribe scribe, ASTWriterVisitor visitor, - ModificationScopeStack stack, NodeCommentMap commentMap) { + ModificationScopeStack stack, NodeCommentMap commentMap, boolean placeConstRight) { super(scribe, visitor, commentMap); + setPlaceConstRight(placeConstRight); this.modificationHelper = new ASTModificationHelper(stack); } diff --git a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/CCorePreferenceConstants.java b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/CCorePreferenceConstants.java index f8f46dfa2b1..ac9550b81e1 100644 --- a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/CCorePreferenceConstants.java +++ b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/CCorePreferenceConstants.java @@ -349,6 +349,21 @@ public class CCorePreferenceConstants { // NOTE: This default came from measurements using a 1Gb heap on a 64-bit VM. The test project was // boost-1.55.0. This default will index all but 9 files without running out of memory. + /** + * A named preference that specifies whether the const qualifier is written to the right (or left) of + * the type in a declaration specifier. + * + * @since 6.3 + */ + public static final String PLACE_CONST_RIGHT_OF_TYPE = "astwriter.placeConstRightOfType"; //$NON-NLS-1$ + + /** + * Default value for {@link #PLACE_CONST_RIGHT_OF_TYPE}. + * + * @since 6.3 + */ + public static final boolean DEFAULT_PLACE_CONST_RIGHT_OF_TYPE = false; + /** * Returns the node in the preference in the given context. * diff --git a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/core/CCorePreferenceInitializer.java b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/core/CCorePreferenceInitializer.java index 2efc270b1be..98604ef2bca 100644 --- a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/core/CCorePreferenceInitializer.java +++ b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/core/CCorePreferenceInitializer.java @@ -75,5 +75,6 @@ public class CCorePreferenceInitializer extends AbstractPreferenceInitializer { defaultPreferences.putInt(CCorePreferenceConstants.SCALABILITY_MAXIMUM_TRIVIAL_EXPRESSIONS, CCorePreferenceConstants.DEFAULT_SCALABILITY_MAXIMUM_TRIVIAL_EXPRESSIONS); defaultPreferences.putBoolean(CCorePreferenceConstants.SCALABILITY_LIMIT_TOKENS_PER_TU, CCorePreferenceConstants.DEFAULT_SCALABILITY_LIMIT_TOKENS_PER_TU); defaultPreferences.putInt(CCorePreferenceConstants.SCALABILITY_MAXIMUM_TOKENS, CCorePreferenceConstants.DEFAULT_SCALABILITY_MAXIMUM_TOKENS); + defaultPreferences.putBoolean(CCorePreferenceConstants.PLACE_CONST_RIGHT_OF_TYPE, CCorePreferenceConstants.DEFAULT_PLACE_CONST_RIGHT_OF_TYPE); } } diff --git a/core/org.eclipse.cdt.ui.tests/resources/constalign/leftChanged/After.cpp b/core/org.eclipse.cdt.ui.tests/resources/constalign/leftChanged/After.cpp new file mode 100644 index 00000000000..658556eec44 --- /dev/null +++ b/core/org.eclipse.cdt.ui.tests/resources/constalign/leftChanged/After.cpp @@ -0,0 +1,28 @@ + +void f(const int * const); + +void f(const int * const) { + +} + +int main(int argc, char **argv) { + + const int &dsa { 2 }; + + const int j { 8 }; + + const int * const klz; + + const int l { 2 }; + + bool yes = false; + + const int k { 42 }; + + const volatile int q = 1; + + volatile const int r = 99; + + using const_int = int; + const const_int s = 7; +}
\ No newline at end of file diff --git a/core/org.eclipse.cdt.ui.tests/resources/constalign/leftChanged/Before.cpp b/core/org.eclipse.cdt.ui.tests/resources/constalign/leftChanged/Before.cpp new file mode 100644 index 00000000000..71fc943a67f --- /dev/null +++ b/core/org.eclipse.cdt.ui.tests/resources/constalign/leftChanged/Before.cpp @@ -0,0 +1,29 @@ + +void f(int const * const); + +void f(int const * const) { + +} + +int main(int argc, char **argv) { + + int const &dsa { 2 }; + + int const j { 8 }; + + int const * const klz; + + int const l { 2 }; + + bool yes = false; + + int const k { 42 }; + + volatile int + const q = 1; + + volatile const int r = 99; + + using const_int = int; + const_int const s = 7; +}
\ No newline at end of file diff --git a/core/org.eclipse.cdt.ui.tests/resources/constalign/leftUnchanged/After.cpp b/core/org.eclipse.cdt.ui.tests/resources/constalign/leftUnchanged/After.cpp new file mode 100644 index 00000000000..84a0ff7214e --- /dev/null +++ b/core/org.eclipse.cdt.ui.tests/resources/constalign/leftUnchanged/After.cpp @@ -0,0 +1,27 @@ + +void f(const int * const); + +void f(const int * const) { + +} + +int main(int argc, char **argv) { + + const int &dsa { 2 }; + + const int j { 8 }; + + const int * const klz; + + const int l { 2 }; + + bool yes = false; + + const int k { 42 }; + + volatile const + int q = 1; + + using int_const = int; + const int_const r = 7; +}
\ No newline at end of file diff --git a/core/org.eclipse.cdt.ui.tests/resources/constalign/leftUnchanged/Before.cpp b/core/org.eclipse.cdt.ui.tests/resources/constalign/leftUnchanged/Before.cpp new file mode 100644 index 00000000000..84a0ff7214e --- /dev/null +++ b/core/org.eclipse.cdt.ui.tests/resources/constalign/leftUnchanged/Before.cpp @@ -0,0 +1,27 @@ + +void f(const int * const); + +void f(const int * const) { + +} + +int main(int argc, char **argv) { + + const int &dsa { 2 }; + + const int j { 8 }; + + const int * const klz; + + const int l { 2 }; + + bool yes = false; + + const int k { 42 }; + + volatile const + int q = 1; + + using int_const = int; + const int_const r = 7; +}
\ No newline at end of file diff --git a/core/org.eclipse.cdt.ui.tests/resources/constalign/rightChanged/After.cpp b/core/org.eclipse.cdt.ui.tests/resources/constalign/rightChanged/After.cpp new file mode 100644 index 00000000000..d46d4b9ee53 --- /dev/null +++ b/core/org.eclipse.cdt.ui.tests/resources/constalign/rightChanged/After.cpp @@ -0,0 +1,26 @@ + +void f(int const * const); + +void f(int const * const) { + +} + +int main(int argc, char **argv) { + + int const &dsa { 2 }; + + int const j { 8 }; + + int const * const klz; + + int const l { 2 }; + + bool yes = false; + + int const k { 42 }; + + volatile int const q = 1; + + using int_const = int; + int_const const r = 7; +}
\ No newline at end of file diff --git a/core/org.eclipse.cdt.ui.tests/resources/constalign/rightChanged/Before.cpp b/core/org.eclipse.cdt.ui.tests/resources/constalign/rightChanged/Before.cpp new file mode 100644 index 00000000000..84a0ff7214e --- /dev/null +++ b/core/org.eclipse.cdt.ui.tests/resources/constalign/rightChanged/Before.cpp @@ -0,0 +1,27 @@ + +void f(const int * const); + +void f(const int * const) { + +} + +int main(int argc, char **argv) { + + const int &dsa { 2 }; + + const int j { 8 }; + + const int * const klz; + + const int l { 2 }; + + bool yes = false; + + const int k { 42 }; + + volatile const + int q = 1; + + using int_const = int; + const int_const r = 7; +}
\ No newline at end of file diff --git a/core/org.eclipse.cdt.ui.tests/resources/constalign/rightUnchanged/After.cpp b/core/org.eclipse.cdt.ui.tests/resources/constalign/rightUnchanged/After.cpp new file mode 100644 index 00000000000..1120cb7499e --- /dev/null +++ b/core/org.eclipse.cdt.ui.tests/resources/constalign/rightUnchanged/After.cpp @@ -0,0 +1,29 @@ + +void f(int const * const); + +void f(int const * const) { + +} + +int main(int argc, char **argv) { + + int const &dsa { 2 }; + + int const j { 8 }; + + int const * const klz; + + int const l { 2 }; + + bool yes = false; + + int const k { 42 }; + + int const volatile m = 21; + + using volatile_int = int; + volatile_int const volatile v = 89; + + using const_int = int; + const_int const w = 73; +}
\ No newline at end of file diff --git a/core/org.eclipse.cdt.ui.tests/resources/constalign/rightUnchanged/Before.cpp b/core/org.eclipse.cdt.ui.tests/resources/constalign/rightUnchanged/Before.cpp new file mode 100644 index 00000000000..1120cb7499e --- /dev/null +++ b/core/org.eclipse.cdt.ui.tests/resources/constalign/rightUnchanged/Before.cpp @@ -0,0 +1,29 @@ + +void f(int const * const); + +void f(int const * const) { + +} + +int main(int argc, char **argv) { + + int const &dsa { 2 }; + + int const j { 8 }; + + int const * const klz; + + int const l { 2 }; + + bool yes = false; + + int const k { 42 }; + + int const volatile m = 21; + + using volatile_int = int; + volatile_int const volatile v = 89; + + using const_int = int; + const_int const w = 73; +}
\ No newline at end of file diff --git a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/AlignConstActionTest.java b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/AlignConstActionTest.java new file mode 100644 index 00000000000..e822e9c9ae1 --- /dev/null +++ b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/AlignConstActionTest.java @@ -0,0 +1,130 @@ +/******************************************************************************* + * Copyright (c) 2016 Institute for Software, HSR Hochschule fuer Technik + * Rapperswil, University of applied sciences. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + *******************************************************************************/ +package org.eclipse.cdt.ui.tests.text; + +import java.util.ListResourceBundle; + +import org.eclipse.core.runtime.preferences.DefaultScope; +import org.eclipse.core.runtime.preferences.IEclipsePreferences; +import org.eclipse.jface.text.IDocument; +import org.eclipse.jface.text.source.SourceViewer; + +import org.eclipse.cdt.core.CCorePlugin; +import org.eclipse.cdt.core.CCorePreferenceConstants; +import org.eclipse.cdt.core.model.ICProject; +import org.eclipse.cdt.core.testplugin.CProjectHelper; +import org.eclipse.cdt.ui.testplugin.EditorTestHelper; +import org.eclipse.cdt.ui.testplugin.ResourceTestHelper; + +import org.eclipse.cdt.internal.ui.actions.AlignConstAction; +import org.eclipse.cdt.internal.ui.editor.CEditor; + +import junit.extensions.TestSetup; +import junit.framework.Test; +import junit.framework.TestCase; +import junit.framework.TestSuite; + +/** + * Test for the const alignment action. + */ +public class AlignConstActionTest extends TestCase { + private static final String PROJECT = "AlignConstTests"; + + private static final class EmptyBundle extends ListResourceBundle { + @Override + protected Object[][] getContents() { + return new Object[0][]; + } + } + + protected static class AlignConstTestSetup extends TestSetup { + private ICProject fCProject; + + public AlignConstTestSetup(Test test) { + super(test); + } + + @Override + protected void setUp() throws Exception { + super.setUp(); + fCProject = EditorTestHelper.createCProject(PROJECT, "resources/constalign"); + } + + @Override + protected void tearDown() throws Exception { + if (fCProject != null) + CProjectHelper.delete(fCProject); + super.tearDown(); + } + } + + public static Test suite() { + return new AlignConstTestSetup(new TestSuite(AlignConstActionTest.class)); + } + + private CEditor fEditor; + private SourceViewer fSourceViewer; + private IDocument fDocument; + + @Override + protected void setUp() throws Exception { + IEclipsePreferences prefs = DefaultScope.INSTANCE.getNode(CCorePlugin.PLUGIN_ID); + prefs.putBoolean(CCorePreferenceConstants.PLACE_CONST_RIGHT_OF_TYPE, getName().startsWith("testRight")); + String filename = createFileName("Before"); + fEditor = (CEditor) EditorTestHelper.openInEditor(ResourceTestHelper.findFile(filename), true); + fSourceViewer = EditorTestHelper.getSourceViewer(fEditor); + fDocument = fSourceViewer.getDocument(); + } + + @Override + protected void tearDown() throws Exception { + EditorTestHelper.closeEditor(fEditor); + IEclipsePreferences prefs = DefaultScope.INSTANCE.getNode(CCorePlugin.PLUGIN_ID); + prefs.putBoolean(CCorePreferenceConstants.PLACE_CONST_RIGHT_OF_TYPE, false); + } + + private void assertAlignConstResult() throws Exception { + String afterFile = createFileName("After"); + String expected = ResourceTestHelper.read(afterFile).toString(); + + new AlignConstAction(new EmptyBundle(), "prefix", fEditor).run(); + + assertEquals(expected, fDocument.get()); + } + + private String createFileName(String qualifier) { + String name = getName(); + name = name.substring(4, 5).toLowerCase() + name.substring(5); + return "/" + PROJECT + "/src/" + name + "/" + qualifier + ".cpp"; + } + + private void selectAll() { + fSourceViewer.setSelectedRange(0, fDocument.getLength()); + } + + public void testRightUnchanged() throws Exception { + selectAll(); + assertAlignConstResult(); + } + + public void testRightChanged() throws Exception { + selectAll(); + assertAlignConstResult(); + } + + public void testLeftUnchanged() throws Exception { + selectAll(); + assertAlignConstResult(); + } + + public void testLeftChanged() throws Exception { + selectAll(); + assertAlignConstResult(); + } +}
\ No newline at end of file diff --git a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/TextTestSuite.java b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/TextTestSuite.java index 96d650122ee..5e9ee52e523 100644 --- a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/TextTestSuite.java +++ b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/TextTestSuite.java @@ -31,6 +31,7 @@ import org.eclipse.cdt.ui.tests.text.doctools.DocCommentTestSuite; AsmPartitionerTest.class, // smart edit tests + AlignConstActionTest.class, CAutoIndentTest.class, CHeuristicScannerTest.class, BracketInserterTest.class, diff --git a/core/org.eclipse.cdt.ui/plugin.properties b/core/org.eclipse.cdt.ui/plugin.properties index 00cda2d3a7b..65d5a89661d 100644 --- a/core/org.eclipse.cdt.ui/plugin.properties +++ b/core/org.eclipse.cdt.ui/plugin.properties @@ -123,6 +123,9 @@ ActionDefinition.removeBlockComment.description= Removes the block comment enclo ActionDefinition.indent.name= Indent Line ActionDefinition.indent.description=Indents the current line +ActionDefinition.alignConst.name= Align const qualifiers +ActionDefinition.alignConst.description= Moves const qualifiers to the left or right of the type depending on the workspace preferences + ActionDefinition.format.name=Format ActionDefinition.format.description=Formats Source Code @@ -613,6 +616,7 @@ headerFileRenameParticipant.name = Header File Rename FormatAction.label= &Format IndentAction.label= Correct &Indentation +AlignConst.label= &Align Const OrganizeIncludesAction.label= Or&ganize Includes AddIncludeAction.label= A&dd Include SortLinesAction.label= Sor&t Lines diff --git a/core/org.eclipse.cdt.ui/plugin.xml b/core/org.eclipse.cdt.ui/plugin.xml index d90fbcd062b..20644ae7931 100644 --- a/core/org.eclipse.cdt.ui/plugin.xml +++ b/core/org.eclipse.cdt.ui/plugin.xml @@ -1957,6 +1957,13 @@ id="org.eclipse.cdt.ui.actions.Indent"> </action> <action + definitionId="org.eclipse.cdt.ui.edit.text.c.align.const" + label="%AlignConst.label" + retarget="true" + menubarPath="org.eclipse.jdt.ui.source.menu/editGroup" + id="org.eclipse.cdt.ui.actions.AlignConst"> + </action> + <action definitionId="org.eclipse.ui.edit.text.shiftLeft" disabledIcon="icons/dlcl16/shift_l_edit.gif" icon="icons/elcl16/shift_l_edit.gif" @@ -2398,6 +2405,11 @@ commandId="org.eclipse.cdt.ui.edit.text.c.indent" schemeId="org.eclipse.ui.defaultAcceleratorConfiguration"/> <key + sequence="M1+M2+A" + contextId="org.eclipse.cdt.ui.cEditorScope" + commandId="org.eclipse.cdt.ui.edit.text.c.align.const" + schemeId="org.eclipse.ui.defaultAcceleratorConfiguration"/> + <key sequence="M2+M3+Z" contextId="org.eclipse.cdt.ui.cEditorScope" commandId="org.eclipse.cdt.ui.edit.text.c.surround.with.quickMenu" @@ -3218,6 +3230,12 @@ categoryId="org.eclipse.ui.category.edit" id="org.eclipse.cdt.ui.edit.text.c.select.last"> </command> + <command + categoryId="org.eclipse.cdt.ui.category.source" + description="%ActionDefinition.alignConst.description" + id="org.eclipse.cdt.ui.edit.text.c.align.const" + name="%ActionDefinition.alignConst.name"> + </command> </extension> <extension id="pdomSearchPage" @@ -4935,6 +4953,9 @@ <key name="markOverloadedOperatorsOccurrences"/> <key name="scalability." match="prefix"/> <key name="content_assist_proposals_timeout"/> + <key + name="alignConst"> + </key> </entry> </mapping> <description> @@ -4958,6 +4979,12 @@ <key name="nameStyle." match="prefix"/> <key name="organizeIncludes." match="prefix"/> </entry> + <entry + node="org.eclipse.cdt.core"> + <key + name="astwriter.placeConstRightOfType"> + </key> + </entry> </mapping> <description> %transfer.CodeStyle.description diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/actions/ActionMessages.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/actions/ActionMessages.java index 82c5a11fa5a..c95c7d25816 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/actions/ActionMessages.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/actions/ActionMessages.java @@ -93,6 +93,9 @@ public class ActionMessages extends NLS { public static String FormatAllAction_failedvalidateedit_message; public static String FormatAllAction_noundo_title; public static String FormatAllAction_noundo_message; + public static String AlignAllConstAction_label; + public static String AlignAllConstAction_tooltip; + public static String AlignAllConstAction_description; public static String CollapseAllAction_label; public static String CollapseAllAction_tooltip; public static String CollapseAllAction_description; diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/actions/ActionMessages.properties b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/actions/ActionMessages.properties index fa2808c76ce..31e7ba70bee 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/actions/ActionMessages.properties +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/actions/ActionMessages.properties @@ -113,6 +113,10 @@ FormatAllAction_failedvalidateedit_message=Problems while accessing selected fil FormatAllAction_noundo_title=Format FormatAllAction_noundo_message='Undo' is not supported by this operation. Do you want to continue? +AlignAllConstAction_label=Align const +AlignAllConstAction_tooltip=Align all const qualifiers +AlignAllConstAction_description=Aligns all const qualifiers relative to the corresponding type + CollapseAllAction_label=Collapse All CollapseAllAction_tooltip=Collapse All CollapseAllAction_description=Collapse All diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/actions/AlignConstAction.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/actions/AlignConstAction.java new file mode 100644 index 00000000000..048c38acbd3 --- /dev/null +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/actions/AlignConstAction.java @@ -0,0 +1,180 @@ +/******************************************************************************* + * Copyright (c) 2016 Institute for Software, HSR Hochschule fuer Technik + * Rapperswil, University of applied sciences. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + *******************************************************************************/ +package org.eclipse.cdt.internal.ui.actions; + +import java.util.ArrayList; +import java.util.List; +import java.util.ResourceBundle; + +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.NullProgressMonitor; +import org.eclipse.jface.text.ITextSelection; +import org.eclipse.jface.text.TextSelection; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.ISelectionProvider; +import org.eclipse.ui.texteditor.ITextEditor; +import org.eclipse.ui.texteditor.TextEditorAction; + +import org.eclipse.cdt.core.CCorePreferenceConstants; +import org.eclipse.cdt.core.dom.ast.ASTVisitor; +import org.eclipse.cdt.core.dom.ast.IASTDeclSpecifier; +import org.eclipse.cdt.core.dom.ast.IASTNode; +import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit; +import org.eclipse.cdt.core.dom.rewrite.ASTRewrite; +import org.eclipse.cdt.core.model.ICProject; +import org.eclipse.cdt.core.model.ITranslationUnit; +import org.eclipse.cdt.core.parser.Keywords; +import org.eclipse.cdt.ui.CDTUITools; +import org.eclipse.cdt.ui.CUIPlugin; + +import org.eclipse.cdt.internal.ui.refactoring.utils.IdentifierHelper; + +public class AlignConstAction extends TextEditorAction { + + private static class MisalignedConstFinderVisitor extends ASTVisitor { + private final boolean expectConstRight; + private final List<IASTDeclSpecifier> declSpecifiersWithMisalignedConst = new ArrayList<>(); + { + shouldVisitDeclSpecifiers = true; + } + + public MisalignedConstFinderVisitor(boolean expectConstRight) { + this.expectConstRight = expectConstRight; + } + + @Override + public int visit(IASTDeclSpecifier declSpec) { + if (declSpec.isConst()) { + String rawSignature = declSpec.getRawSignature(); + rawSignature = rawSignature.replace(Keywords.VOLATILE, "").trim(); //$NON-NLS-1$ + if (!expectConstRight && !startsWithConst(rawSignature)) { + declSpecifiersWithMisalignedConst.add(declSpec); + } else if (expectConstRight && !endsWithConst(rawSignature)) { + declSpecifiersWithMisalignedConst.add(declSpec); + } + } + return PROCESS_CONTINUE; + } + + private boolean startsWithConst(String signature) { + if (!signature.startsWith(Keywords.CONST)) { + return false; + } + String candidate = signature.substring(0, Keywords.CONST.length() + 1); + return !IdentifierHelper.checkIdentifierName(candidate).isCorrect(); + } + + private boolean endsWithConst(String signature) { + if (!signature.endsWith(Keywords.CONST)) { + return false; + } + String candidate = signature.substring(signature.length() - Keywords.CONST.length() - 1); + return !IdentifierHelper.checkIdentifierName(candidate).isCorrect(); + } + + public List<IASTDeclSpecifier> getDeclSpecifiersWithMisaligedConst() { + return declSpecifiersWithMisalignedConst; + } + } + + private static List<IASTDeclSpecifier> findMisalignedConsts(IASTNode rootNode, ICProject cProject) { + boolean expectConstRight = CCorePreferenceConstants.getPreference( + CCorePreferenceConstants.PLACE_CONST_RIGHT_OF_TYPE, cProject, + CCorePreferenceConstants.DEFAULT_PLACE_CONST_RIGHT_OF_TYPE); + MisalignedConstFinderVisitor misalignedConstVisitor = new MisalignedConstFinderVisitor( + expectConstRight); + rootNode.accept(misalignedConstVisitor); + return misalignedConstVisitor.getDeclSpecifiersWithMisaligedConst(); + } + + public static void rewriteMisalignedConstSpecifiers(IASTNode node, IProgressMonitor monitor) + throws CoreException { + ICProject cProject = node.getTranslationUnit().getOriginatingTranslationUnit().getCProject(); + List<IASTDeclSpecifier> misalignedSpecifiers = findMisalignedConsts(node, cProject); + if (!misalignedSpecifiers.isEmpty()) { + IASTTranslationUnit ast = node.getTranslationUnit(); + ASTRewrite rewrite = ASTRewrite.create(ast); + for (IASTDeclSpecifier spec : misalignedSpecifiers) { + rewrite.replace(spec, spec, null); + } + rewrite.rewriteAST().perform(monitor); + } + } + + /** + * Creates a new AlignConstAction instance. + * + * @param bundle + * the resource bundle + * @param prefix + * the prefix to use for keys in <code>bundle</code> + * @param editor + * the text editor + */ + public AlignConstAction(ResourceBundle bundle, String prefix, ITextEditor editor) { + super(bundle, prefix, editor); + } + + @Override + public void run() { + ITextSelection textSelection = getSelection(); + if (textSelection.isEmpty()) { + return; + } + final int offset = textSelection.getOffset(); + final int length = textSelection.getLength(); + ITextEditor activeEditor = getTextEditor(); + + alignConstQualifiers(offset, length, activeEditor); + } + + private void alignConstQualifiers(final int offset, final int length, ITextEditor activeEditor) { + ITranslationUnit translationUnit = (ITranslationUnit) CDTUITools + .getEditorInputCElement(activeEditor.getEditorInput()); + + try { + IASTTranslationUnit ast = translationUnit.getAST(null, ITranslationUnit.AST_SKIP_ALL_HEADERS); + IASTNode enclosingNode = ast.getNodeSelector(null).findEnclosingNode(offset, length); + rewriteMisalignedConstSpecifiers(enclosingNode, new NullProgressMonitor()); + } catch (CoreException e) { + CUIPlugin.log(e); + } + } + + /** + * Returns the selection in the editor or an invalid selection if none can + * be obtained. Never returns <code>null</code>. + * + * @return the current selection, never <code>null</code> + */ + private ITextSelection getSelection() { + ISelectionProvider provider = getSelectionProvider(); + if (provider != null) { + ISelection selection = provider.getSelection(); + if (selection instanceof ITextSelection) + return (ITextSelection) selection; + } + + return TextSelection.emptySelection(); + } + + /** + * Returns the editor's selection provider. + * + * @return the editor's selection provider or <code>null</code> + */ + private ISelectionProvider getSelectionProvider() { + ITextEditor editor = getTextEditor(); + if (editor != null) { + return editor.getSelectionProvider(); + } + return null; + } +}
\ No newline at end of file diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/CDocumentProvider.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/CDocumentProvider.java index afefc1a5972..108e7aa3d2d 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/CDocumentProvider.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/CDocumentProvider.java @@ -89,6 +89,7 @@ import org.eclipse.cdt.ui.text.ICPartitions; import org.eclipse.cdt.internal.core.model.TranslationUnit; +import org.eclipse.cdt.internal.ui.saveactions.AlignConstSaveAction; import org.eclipse.cdt.internal.ui.text.IProblemRequestorExtension; import org.eclipse.cdt.internal.ui.text.spelling.CoreSpellingProblem; import org.eclipse.cdt.internal.ui.util.EditorUtility; @@ -964,8 +965,8 @@ public class CDocumentProvider extends TextFileDocumentProvider { */ private void performSaveActions(ITranslationUnit tu, ITextFileBuffer buffer, IProgressMonitor monitor) throws CoreException { - if (shouldRemoveTrailingWhitespace() || shouldAddNewlineAtEof() || shouldFormatCode()) { - SubMonitor progress = SubMonitor.convert(monitor, 2); + if (shouldRemoveTrailingWhitespace() || shouldAddNewlineAtEof() || shouldFormatCode() || shouldAlignAllConst()) { + SubMonitor progress = SubMonitor.convert(monitor, 3); IDocumentUndoManager undoManager= null; IRegion[] changedRegions= needsChangedRegions() ? EditorUtility.calculateChangedLineRegions(buffer, progress.split(1)) : null; @@ -992,6 +993,11 @@ public class CDocumentProvider extends TextFileDocumentProvider { } edit.apply(document); } + + if (shouldAlignAllConst()) { + new AlignConstSaveAction().perform(tu, progress.split(1)); + } + } catch (MalformedTreeException | BadLocationException e) { String message= e.getMessage(); if (message == null) @@ -1028,6 +1034,11 @@ public class CDocumentProvider extends TextFileDocumentProvider { PreferenceConstants.REMOVE_TRAILING_WHITESPACE_LIMIT_TO_EDITED_LINES); } + private static boolean shouldAlignAllConst() { + return PreferenceConstants.getPreferenceStore().getBoolean( + PreferenceConstants.ALIGN_ALL_CONST); + } + private static boolean needsChangedRegions() { return shouldRemoveTrailingWhitespace() && isLimitedRemoveTrailingWhitespace() || shouldFormatCode() && isLimitedFormatCode(); diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/CEditor.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/CEditor.java index f4dc883349d..90cab566692 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/CEditor.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/CEditor.java @@ -212,6 +212,7 @@ import org.eclipse.cdt.internal.ui.CPluginImages; import org.eclipse.cdt.internal.ui.ICHelpContextIds; import org.eclipse.cdt.internal.ui.IContextMenuConstants; import org.eclipse.cdt.internal.ui.actions.AddBlockCommentAction; +import org.eclipse.cdt.internal.ui.actions.AlignConstAction; import org.eclipse.cdt.internal.ui.actions.FindWordAction; import org.eclipse.cdt.internal.ui.actions.FoldingActionGroup; import org.eclipse.cdt.internal.ui.actions.GoToNextPreviousMemberAction; @@ -2284,6 +2285,12 @@ public class CEditor extends TextEditor implements ICEditor, ISelectionChangedLi markAsSelectionDependentAction("Indent", true); //$NON-NLS-1$ // PlatformUI.getWorkbench().getHelpSystem().setHelp(action, ICHelpContextIds.INDENT_ACTION); + action = new AlignConstAction(bundle, "AlignConst.", this); //$NON-NLS-1$ + action.setActionDefinitionId(ICEditorActionDefinitionIds.ALIGN_CONST); + setAction("AlignConst", action); //$NON-NLS-1$ + markAsStateDependentAction("AlignConst", true); //$NON-NLS-1$ + markAsSelectionDependentAction("AlignConst", true); //$NON-NLS-1$ + action = new IndentAction(bundle, "Indent.", this, true); //$NON-NLS-1$ setAction("IndentOnTab", action); //$NON-NLS-1$ markAsStateDependentAction("IndentOnTab", true); //$NON-NLS-1$ diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/CEditorActionContributor.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/CEditorActionContributor.java index 7fcc047f01a..82905e3fd8c 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/CEditorActionContributor.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/CEditorActionContributor.java @@ -225,6 +225,7 @@ public class CEditorActionContributor extends TextEditorActionContributor { bars.setGlobalActionHandler(CdtActionConstants.ADD_BLOCK_COMMENT, getAction(textEditor, "AddBlockComment")); //$NON-NLS-1$ bars.setGlobalActionHandler(CdtActionConstants.REMOVE_BLOCK_COMMENT, getAction(textEditor, "RemoveBlockComment")); //$NON-NLS-1$ bars.setGlobalActionHandler(CdtActionConstants.INDENT, getAction(textEditor, "Indent")); //$NON-NLS-1$ + bars.setGlobalActionHandler(CdtActionConstants.ALIGN_CONST, getAction(textEditor, "AlignConst")); //$NON-NLS-1$ bars.setGlobalActionHandler(CdtActionConstants.ADD_INCLUDE, getAction(textEditor, "AddInclude")); //$NON-NLS-1$ bars.setGlobalActionHandler(CdtActionConstants.ORGANIZE_INCLUDES, getAction(textEditor, "OrganizeIncludes")); //$NON-NLS-1$ bars.setGlobalActionHandler(CdtActionConstants.SORT_LINES, getAction(textEditor, "SortLines")); //$NON-NLS-1$ diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/ConstructedCEditorMessages.properties b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/ConstructedCEditorMessages.properties index 72da918416c..c1bdfd84fc5 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/ConstructedCEditorMessages.properties +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/ConstructedCEditorMessages.properties @@ -89,6 +89,10 @@ Indent.label=Correct &Indentation Indent.tooltip=&Indent Current Line to Correct Indentation Indent.description=&Indents the current line or selection depending on surrounding source code +AlignConst.label=&Align const +AlignConst.tooltip=&Align const qualifier according to preferences +AlignConst.description=&Aligns const qualified according to preferences + GotoNextMember.label= N&ext Member GotoNextMember.tooltip=Move the Caret to the Next Member of the Translation Unit GotoNextMember.description=Moves the caret to the next member of the translation unit diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/ICEditorActionDefinitionIds.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/ICEditorActionDefinitionIds.java index 7345b917efb..98dfbadc4fc 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/ICEditorActionDefinitionIds.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/ICEditorActionDefinitionIds.java @@ -61,6 +61,12 @@ public interface ICEditorActionDefinitionIds extends ITextEditorActionDefinition public static final String INDENT = "org.eclipse.cdt.ui.edit.text.c.indent"; //$NON-NLS-1$ /** + * Action definition ID of the source -> align const action + * (value <code>"org.eclipse.cdt.ui.edit.text.c.align.const"</code>). + */ + public static final String ALIGN_CONST = "org.eclipse.cdt.ui.edit.text.c.align.const"; //$NON-NLS-1$ + + /** * Action definition ID of the source -> format action * (value <code>"org.eclipse.cdt.ui.edit.text.c.format"</code>). */ diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/preferences/CodeStyleBlock.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/preferences/CodeStyleBlock.java index 609121633ce..5029316fc8f 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/preferences/CodeStyleBlock.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/preferences/CodeStyleBlock.java @@ -18,6 +18,8 @@ import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.ui.preferences.IWorkbenchPreferenceContainer; +import org.eclipse.cdt.core.CCorePlugin; +import org.eclipse.cdt.core.CCorePreferenceConstants; import org.eclipse.cdt.ui.PreferenceConstants; import org.eclipse.cdt.internal.ui.dialogs.IStatusChangeListener; @@ -32,12 +34,15 @@ class CodeStyleBlock extends OptionsConfigurationBlock { getCDTUIKey(PreferenceConstants.FUNCTION_OUTPUT_PARAMETERS_BEFORE_INPUT); private static final Key FUNCTION_PASS_OUTPUT_PARAMETERS_BY_POINTER = getCDTUIKey(PreferenceConstants.FUNCTION_PASS_OUTPUT_PARAMETERS_BY_POINTER); + private static final Key PLACE_CONST_RIGHT_OF_TYPE = + getKey(CCorePlugin.PLUGIN_ID, CCorePreferenceConstants.PLACE_CONST_RIGHT_OF_TYPE); private static Key[] getAllKeys() { return new Key[] { CLASS_MEMBER_ASCENDING_VISIBILITY_ORDER, FUNCTION_OUTPUT_PARAMETERS_BEFORE_INPUT, FUNCTION_PASS_OUTPUT_PARAMETERS_BY_POINTER, + PLACE_CONST_RIGHT_OF_TYPE, }; } @@ -64,6 +69,9 @@ class CodeStyleBlock extends OptionsConfigurationBlock { composite = addSubsection(control, PreferencesMessages.CodeStyleBlock_function_output_parameter_style); fillFunctionOutputParameterStyleSection(composite); + + composite = addSubsection(control, PreferencesMessages.CodeStyleBlock_const_keyword_placement); + fillConstPlacementsSections(composite); scrolled.setContent(control); final Point size= control.computeSize(SWT.DEFAULT, SWT.DEFAULT); @@ -104,6 +112,17 @@ class CodeStyleBlock extends OptionsConfigurationBlock { FUNCTION_PASS_OUTPUT_PARAMETERS_BY_POINTER, TRUE_FALSE, 0); } + private void fillConstPlacementsSections(Composite composite) { + GridLayout layout= new GridLayout(); + layout.numColumns= 3; + composite.setLayout(layout); + + addRadioButton(composite, PreferencesMessages.CodeStyleBlock_const_left, + PLACE_CONST_RIGHT_OF_TYPE, FALSE_TRUE, 0); + addRadioButton(composite, PreferencesMessages.CodeStyleBlock_const_right, + PLACE_CONST_RIGHT_OF_TYPE, TRUE_FALSE, 0); + } + @Override protected void validateSettings(Key changedKey, String oldValue, String newValue) { } diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/preferences/PreferencesMessages.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/preferences/PreferencesMessages.java index 787047ad478..981edd57701 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/preferences/PreferencesMessages.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/preferences/PreferencesMessages.java @@ -190,6 +190,7 @@ public final class PreferencesMessages extends NLS { public static String SaveActionsPreferencePage_inAllLines; public static String SaveActionsPreferencePage_inEditedLines; public static String SaveActionsPreferencePage_ensureNewline; + public static String SaveActionsPreferencePage_alignConst; public static String SmartTypingConfigurationBlock_autoclose_title; public static String SmartTypingConfigurationBlock_autoindent_newlines; @@ -217,6 +218,9 @@ public final class PreferencesMessages extends NLS { public static String CodeStyleBlock_function_output_parameter_style; public static String CodeStyleBlock_pass_by_reference; public static String CodeStyleBlock_pass_by_pointer; + public static String CodeStyleBlock_const_keyword_placement; + public static String CodeStyleBlock_const_left; + public static String CodeStyleBlock_const_right; public static String TodoTaskPreferencePage_title; public static String TodoTaskPreferencePage_description; diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/preferences/PreferencesMessages.properties b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/preferences/PreferencesMessages.properties index d7335f589e4..d54aa891d6f 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/preferences/PreferencesMessages.properties +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/preferences/PreferencesMessages.properties @@ -120,6 +120,7 @@ SaveActionsPreferencePage_removeTrailingWhitespace=Remove trailing &whitespace SaveActionsPreferencePage_inAllLines=In all line&s SaveActionsPreferencePage_inEditedLines=In edi&ted lines SaveActionsPreferencePage_ensureNewline=Ensure &newline at the end of file +SaveActionsPreferencePage_alignConst=Align Const TemplatePreferencePage_Viewer_preview=Preview: @@ -252,6 +253,9 @@ CodeStyleBlock_output_input=&Output parameters first CodeStyleBlock_function_output_parameter_style=Output parameters of C++ functions: CodeStyleBlock_pass_by_reference=Pass by &reference CodeStyleBlock_pass_by_pointer=Pass by poi&nter +CodeStyleBlock_const_keyword_placement=Placement of the const keyword: +CodeStyleBlock_const_left=&Left of type e.g. "const int n{};" +CodeStyleBlock_const_right=&Right of type e.g. "int const n{};" # Task tags. TodoTaskPreferencePage_title=Task Tags diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/preferences/SaveActionsPreferencePage.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/preferences/SaveActionsPreferencePage.java index d8e535cf411..77fd6421981 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/preferences/SaveActionsPreferencePage.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/preferences/SaveActionsPreferencePage.java @@ -16,6 +16,7 @@ import static org.eclipse.cdt.ui.PreferenceConstants.FORMAT_SOURCE_CODE; import static org.eclipse.cdt.ui.PreferenceConstants.FORMAT_SOURCE_CODE_LIMIT_TO_EDITED_LINES; import static org.eclipse.cdt.ui.PreferenceConstants.REMOVE_TRAILING_WHITESPACE; import static org.eclipse.cdt.ui.PreferenceConstants.REMOVE_TRAILING_WHITESPACE_LIMIT_TO_EDITED_LINES; +import static org.eclipse.cdt.ui.PreferenceConstants.ALIGN_ALL_CONST; import java.util.ArrayList; @@ -58,6 +59,8 @@ public class SaveActionsPreferencePage extends AbstractPreferencePage { REMOVE_TRAILING_WHITESPACE_LIMIT_TO_EDITED_LINES)); overlayKeys.add(new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, ENSURE_NEWLINE_AT_EOF)); + overlayKeys.add(new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, + ALIGN_ALL_CONST)); OverlayPreferenceStore.OverlayKey[] keys = new OverlayPreferenceStore.OverlayKey[overlayKeys.size()]; overlayKeys.toArray(keys); @@ -123,6 +126,11 @@ public class SaveActionsPreferencePage extends AbstractPreferencePage { addCheckBox(composite, PreferencesMessages.SaveActionsPreferencePage_ensureNewline, ENSURE_NEWLINE_AT_EOF, 0); + ControlFactory.createEmptySpace(composite, 1); + + addCheckBox(composite, PreferencesMessages.SaveActionsPreferencePage_alignConst, + ALIGN_ALL_CONST, 0); + return composite; } diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/NameInformation.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/NameInformation.java index f3d2c356015..a6832355b7c 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/NameInformation.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/NameInformation.java @@ -29,6 +29,7 @@ import org.eclipse.cdt.core.dom.ast.IASTParameterDeclaration; import org.eclipse.cdt.core.dom.ast.IASTPointerOperator; import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclSpecifier; import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration; +import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit; import org.eclipse.cdt.core.dom.ast.INodeFactory; import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTranslationUnit; @@ -213,11 +214,12 @@ public class NameInformation { public String getTypeName() { if (newTypeName != null) return newTypeName; - INodeFactory nodeFactory = name.getTranslationUnit().getASTNodeFactory(); + IASTTranslationUnit translationUnit = name.getTranslationUnit(); + INodeFactory nodeFactory = translationUnit.getASTNodeFactory(); IASTParameterDeclaration declaration = getParameterDeclaration(nodeFactory, null); if (declaration == null) return null; - ASTWriterVisitor writer = new ASTWriterVisitor(); + ASTWriterVisitor writer = new ASTWriterVisitor(translationUnit.getOriginatingTranslationUnit()); declaration.accept(writer); return writer.toString(); } @@ -230,12 +232,13 @@ public class NameInformation { public String getReturnType() { if (!isReturnValue()) return null; - INodeFactory nodeFactory = name.getTranslationUnit().getASTNodeFactory(); + IASTTranslationUnit translationUnit = name.getTranslationUnit(); + INodeFactory nodeFactory = translationUnit.getASTNodeFactory(); IASTDeclarator sourceDeclarator = getDeclarator(); IASTDeclSpecifier declSpec = safeCopy(getDeclSpecifier()); IASTDeclarator declarator = createDeclarator(nodeFactory, sourceDeclarator, null); IASTParameterDeclaration declaration = nodeFactory.newParameterDeclaration(declSpec, declarator); - ASTWriterVisitor writer = new ASTWriterVisitor(); + ASTWriterVisitor writer = new ASTWriterVisitor(translationUnit.getOriginatingTranslationUnit()); declaration.accept(writer); return writer.toString(); } diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/extractfunction/ExtractFunctionRefactoring.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/extractfunction/ExtractFunctionRefactoring.java index f45f300cc19..b6d023fb97a 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/extractfunction/ExtractFunctionRefactoring.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/extractfunction/ExtractFunctionRefactoring.java @@ -1092,7 +1092,7 @@ public class ExtractFunctionRefactoring extends CRefactoring { buf.append(' '); } IASTParameterDeclaration declaration = parameter.getParameterDeclaration(nodeFactory); - ASTWriterVisitor writer = new ASTWriterVisitor(); + ASTWriterVisitor writer = new ASTWriterVisitor(parameter.getTranslationUnit()); declaration.accept(writer); buf.append(writer.toString()); first = false; diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/saveactions/AlignConstSaveAction.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/saveactions/AlignConstSaveAction.java new file mode 100644 index 00000000000..eb05708c4cf --- /dev/null +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/saveactions/AlignConstSaveAction.java @@ -0,0 +1,40 @@ +/******************************************************************************* + * Copyright (c) 2016 Institute for Software, HSR Hochschule fuer Technik + * Rapperswil, University of applied sciences. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + *******************************************************************************/ +package org.eclipse.cdt.internal.ui.saveactions; + +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IProgressMonitor; + +import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit; +import org.eclipse.cdt.core.model.ITranslationUnit; +import org.eclipse.cdt.ui.CUIPlugin; + +import org.eclipse.cdt.internal.ui.actions.AlignConstAction; + +/** + * Save action to align all const specifiers in a given translation unit + * according to the settings in the workspace preferences (left or right to + * type). + * + */ +public class AlignConstSaveAction { + + public void perform(ITranslationUnit tu, IProgressMonitor monitor) { + alignConstInActiveEditor(tu, monitor); + } + + private void alignConstInActiveEditor(ITranslationUnit translationUnit, IProgressMonitor monitor) { + try { + IASTTranslationUnit ast = translationUnit.getAST(null, ITranslationUnit.AST_SKIP_ALL_HEADERS); + AlignConstAction.rewriteMisalignedConstSpecifiers(ast, monitor); + } catch (CoreException e) { + CUIPlugin.log(e); + } + } +} diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/PreferenceConstants.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/PreferenceConstants.java index d8ed62426d3..909f9f9e5b6 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/PreferenceConstants.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/PreferenceConstants.java @@ -2135,6 +2135,13 @@ public class PreferenceConstants { public static final String INCLUDE_STYLE_MATCHING_PATTERN = "includeStyle.matchingPattern"; //$NON-NLS-1$ /** + * Preference key for whether to 'align' the const keyword to a specific position relative to the type name. + * + * @since 6.2 + */ + public static final String ALIGN_ALL_CONST = "alignConst"; //$NON-NLS-1$ + + /** * A named preference that controls whether annotation roll over is used or not. * <p> * Value is of type <code>Boolean</code>. If <code>true</code> the annotation ruler column @@ -2252,6 +2259,7 @@ public class PreferenceConstants { store.setDefault(REMOVE_TRAILING_WHITESPACE_LIMIT_TO_EDITED_LINES, true); store.setDefault(ENSURE_NEWLINE_AT_EOF, true); store.setDefault(FORMAT_SOURCE_CODE, false); + store.setDefault(ALIGN_ALL_CONST, false); store.setDefault(FORMAT_SOURCE_CODE_LIMIT_TO_EDITED_LINES, true); // Formatter profile diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/actions/CdtActionConstants.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/actions/CdtActionConstants.java index 7dffe16d069..bddb8ffe93f 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/actions/CdtActionConstants.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/actions/CdtActionConstants.java @@ -114,7 +114,15 @@ public class CdtActionConstants { * (value <code>"org.eclipse.cdt.ui.actions.Indent"</code>). */ public static final String INDENT= "org.eclipse.cdt.ui.actions.Indent"; //$NON-NLS-1$ - + + /** + * Source menu: name of standard Align Const global action + * (value <code>"org.eclipse.cdt.ui.actions.AlignConst"</code>). + * + * @since 6.2 + */ + public static final String ALIGN_CONST = "org.eclipse.cdt.ui.actions.AlignConst"; //$NON-NLS-1$ + /** * Source menu: name of standard Shift Right action * (value <code>"org.eclipse.cdt.ui.actions.ShiftRight"</code>). diff --git a/debug/org.eclipse.cdt.debug.application/plugin.xml b/debug/org.eclipse.cdt.debug.application/plugin.xml index d8e5e23462b..fb77efdcf20 100644 --- a/debug/org.eclipse.cdt.debug.application/plugin.xml +++ b/debug/org.eclipse.cdt.debug.application/plugin.xml @@ -132,6 +132,10 @@ </activityPatternBinding> <activityPatternBinding activityId="org.eclipse.cdt.debug.application.activity.filterMenus" + pattern="org.eclipse.cdt.ui/org.eclipse.cdt.ui.actions.AlignConst"> + </activityPatternBinding> + <activityPatternBinding + activityId="org.eclipse.cdt.debug.application.activity.filterMenus" pattern="org.eclipse.cdt.ui/org.eclipse.cdt.ui.actions.ShiftLeft"> </activityPatternBinding> <activityPatternBinding |