From a290bdac7ee9785e71da76f08095951ee042153a Mon Sep 17 00:00:00 2001 From: Nathan Ridge Date: Sun, 6 Apr 2014 18:11:35 -0400 Subject: [PATCH] Bug 399149 - Semantic highlighting for context-sensitive keywords Change-Id: Ied967abed9291eb2e9548f23bf2fbb41e898aec2 Signed-off-by: Nathan Ridge Reviewed-on: https://git.eclipse.org/r/24513 Tested-by: Hudson CI Reviewed-by: Sergey Prigogin Tested-by: Sergey Prigogin --- .../eclipse/cdt/core/dom/ast/ASTVisitor.java | 15 ++ .../ast/cpp/ICPPASTFunctionDeclarator.java | 21 +++ .../dom/ast/cpp/ICPPASTVirtSpecifier.java | 47 ++++++ .../cdt/core/dom/ast/cpp/ICPPNodeFactory.java | 3 + .../cdt/internal/core/dom/parser/ASTNode.java | 3 +- .../parser/cpp/CPPASTFunctionDeclarator.java | 60 ++++++-- .../dom/parser/cpp/CPPASTVirtSpecifier.java | 59 ++++++++ .../core/dom/parser/cpp/CPPNodeFactory.java | 7 + .../dom/parser/cpp/GNUCPPSourceParser.java | 10 +- .../resources/semanticHighlighting/SHTest.cpp | 8 + .../tests/text/SemanticHighlightingTest.java | 19 +++ .../ContributedSemanticHighlighting.java | 2 +- .../ui/editor/SemanticHighlighting.java | 79 +--------- .../SemanticHighlightingReconciler.java | 8 + ...SemanticHighlightingWithOwnPreference.java | 98 ++++++++++++ .../ui/editor/SemanticHighlightings.java | 141 +++++++++++++----- .../CEditorColoringConfigurationBlock.java | 32 ++-- 17 files changed, 470 insertions(+), 142 deletions(-) create mode 100644 core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPASTVirtSpecifier.java create mode 100644 core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTVirtSpecifier.java create mode 100644 core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/SemanticHighlightingWithOwnPreference.java diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/ASTVisitor.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/ASTVisitor.java index 6b503b72a15..87373dc745a 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/ASTVisitor.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/ASTVisitor.java @@ -20,6 +20,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCapture; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier; 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.cpp.ICPPASTVirtSpecifier; import org.eclipse.cdt.internal.core.dom.parser.ASTAmbiguousNode; /** @@ -138,6 +139,11 @@ public abstract class ASTVisitor { */ public boolean shouldVisitCaptures= false; + /** + * Set this flag to visit virt-specifiers. + */ + public boolean shouldVisitVirtSpecifiers = false; + /** * Per default inactive nodes are not visited. You can change that by setting * this flag to true. @@ -204,6 +210,7 @@ public abstract class ASTVisitor { shouldVisitTemplateParameters= visitNodes; shouldVisitTranslationUnit= visitNodes; shouldVisitTypeIds= visitNodes; + shouldVisitVirtSpecifiers= visitNodes; } // visit methods @@ -314,6 +321,10 @@ public abstract class ASTVisitor { public int visit(ICASTDesignator designator) { return PROCESS_CONTINUE; } + + public int visit(ICPPASTVirtSpecifier virtSpecifier) { + return PROCESS_CONTINUE; + } // leave methods public int leave(IASTTranslationUnit tu) { @@ -423,6 +434,10 @@ public abstract class ASTVisitor { public int leave(ICASTDesignator designator) { return PROCESS_CONTINUE; } + + public int leave(ICPPASTVirtSpecifier virtSpecifier) { + return PROCESS_CONTINUE; + } /** * @deprecated use {@link IASTTranslationUnit#getComments()}, instead. diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPASTFunctionDeclarator.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPASTFunctionDeclarator.java index 14cb299e7f0..910df43d38d 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPASTFunctionDeclarator.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPASTFunctionDeclarator.java @@ -31,6 +31,11 @@ public interface ICPPASTFunctionDeclarator extends IASTStandardFunctionDeclarato * @since 5.1 */ public static final IASTTypeId[] NO_EXCEPTION_SPECIFICATION = {}; + + /** + * Used as return value for {@link #getVirtSpecifiers()}. + */ + public static final ICPPASTVirtSpecifier[] NO_VIRT_SPECIFIERS = {}; /** * Represents a 'noexcept' specification without an expression. @@ -47,6 +52,8 @@ public interface ICPPASTFunctionDeclarator extends IASTStandardFunctionDeclarato /** @since 5.2 */ public static final ASTNodeProperty TRAILING_RETURN_TYPE = new ASTNodeProperty( "ICPPASTFunctionDeclarator.TRAILING_RETURN_TYPE [IASTTypeId]"); //$NON-NLS-1$ + public static final ASTNodeProperty VIRT_SPECIFIER = new ASTNodeProperty( + "ICPPASTFunctionDeclarator.VIRT_SPECIFIER [ICPPASTVirtSpecifier]"); //$NON-NLS-1$ /** * Is this a const method? @@ -185,7 +192,9 @@ public interface ICPPASTFunctionDeclarator extends IASTStandardFunctionDeclarato * Sets whether this function is declared override. * * @since 5.5 + * @deprecated Use addVirtSpecifier() instead. */ + @Deprecated public void setOverride(boolean isOverride); /** @@ -199,6 +208,18 @@ public interface ICPPASTFunctionDeclarator extends IASTStandardFunctionDeclarato * Sets whether this function is declared final. * * @since 5.5 + * @deprecated Use addVirtSpecifier() instead. */ + @Deprecated public void setFinal(boolean isFinal); + + /** + * Returns the virt-specifiers of this function. + */ + public ICPPASTVirtSpecifier[] getVirtSpecifiers(); + + /** + * Add a virt-specifiers to this function. + */ + public void addVirtSpecifier(ICPPASTVirtSpecifier virtSpecifier); } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPASTVirtSpecifier.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPASTVirtSpecifier.java new file mode 100644 index 00000000000..38551f15235 --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPASTVirtSpecifier.java @@ -0,0 +1,47 @@ +/******************************************************************************* + * Copyright (c) 2014 Nathan Ridge. + * 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 + * + * Contributors: + * Nathan Ridge - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.core.dom.ast.cpp; + +import org.eclipse.cdt.core.dom.ast.IASTNode; + +/** + * A virt-specifier at the end of a function declaration. + * There are two virt-specifiers, 'final' and 'override'. + * + * @noimplement This interface is not intended to be implemented by clients. + * @noextend This interface is not intended to be extended by clients. + */ +public interface ICPPASTVirtSpecifier extends IASTNode { + + public enum SpecifierKind { + /** + * 'final' specifier + */ + Final, + /** + * 'override' specifier + */ + Override + } + + /** + * Return the kind of this virt-specifier. + * The kind is either 'final' or 'override'. + */ + SpecifierKind getKind(); + + @Override + public ICPPASTVirtSpecifier copy(); + + @Override + public ICPPASTVirtSpecifier copy(CopyStyle style); + +} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPNodeFactory.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPNodeFactory.java index c6e9a72bb7d..94f38362bb8 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPNodeFactory.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPNodeFactory.java @@ -30,6 +30,7 @@ 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.ICPPUnaryTypeTransformation.Operator; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTVirtSpecifier.SpecifierKind; import org.eclipse.cdt.core.dom.parser.cpp.ICPPASTAttributeSpecifier; import org.eclipse.cdt.core.parser.IScanner; @@ -380,6 +381,8 @@ public interface ICPPNodeFactory extends INodeFactory { public ICPPASTUsingDirective newUsingDirective(IASTName name); + public ICPPASTVirtSpecifier newVirtSpecifier(SpecifierKind kind); + public ICPPASTVisibilityLabel newVisibilityLabel(int visibility); public ICPPASTWhileStatement newWhileStatement(); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ASTNode.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ASTNode.java index 2db8ffcb1a8..6fa1ae4cc5a 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ASTNode.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ASTNode.java @@ -198,8 +198,9 @@ public abstract class ASTNode implements IASTNode { public IASTFileLocation getFileLocation() { if (fileLocation != null) return fileLocation; - // TODO(sprigogin): The purpose of offset == 0 && length == 0 condition is not clear to me. final int offset = getOffset(); + // Only an empty translation unit should have offset = 0 and length = 0. + // Otherwise these values mean the parser failed to set the offset and length. if (offset < 0 || (offset == 0 && length == 0 && !(this instanceof IASTTranslationUnit))) { return null; } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTFunctionDeclarator.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTFunctionDeclarator.java index ff3fbcee596..16cdb6d8873 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTFunctionDeclarator.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTFunctionDeclarator.java @@ -23,28 +23,27 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTExpression; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionDeclarator; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionDefinition; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTParameterDeclaration; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTVirtSpecifier; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTVirtSpecifier.SpecifierKind; import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionScope; import org.eclipse.cdt.core.parser.util.ArrayUtil; import org.eclipse.cdt.internal.core.dom.parser.ASTQueries; -import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguityParent; /** * Represents a function declarator. */ -public class CPPASTFunctionDeclarator extends CPPASTDeclarator implements ICPPASTFunctionDeclarator, - IASTAmbiguityParent { +public class CPPASTFunctionDeclarator extends CPPASTDeclarator implements ICPPASTFunctionDeclarator { private ICPPASTParameterDeclaration[] parameters; private IASTTypeId[] typeIds = NO_EXCEPTION_SPECIFICATION; private ICPPASTExpression noexceptExpression; private IASTTypeId trailingReturnType; + private ICPPASTVirtSpecifier[] virtSpecifiers = NO_VIRT_SPECIFIERS; private boolean varArgs; private boolean pureVirtual; private boolean isVolatile; private boolean isConst; private boolean isMutable; - private boolean isOverride; - private boolean isFinal; private ICPPFunctionScope scope; @@ -68,8 +67,6 @@ public class CPPASTFunctionDeclarator extends CPPASTDeclarator implements ICPPAS copy.isVolatile = isVolatile; copy.isConst = isConst; copy.isMutable = isMutable; - copy.isOverride = isOverride; - copy.isFinal = isFinal; for (IASTParameterDeclaration param : getParameters()) { copy.addParameterDeclaration(param == null ? null : param.copy(style)); @@ -84,6 +81,9 @@ public class CPPASTFunctionDeclarator extends CPPASTDeclarator implements ICPPAS if (trailingReturnType != null) { copy.setTrailingReturnType(trailingReturnType.copy(style)); } + for (ICPPASTVirtSpecifier virtSpecifier : getVirtSpecifiers()) { + copy.addVirtSpecifier(virtSpecifier.copy(style)); + } return copy(copy, style); } @@ -265,9 +265,10 @@ public class CPPASTFunctionDeclarator extends CPPASTDeclarator implements ICPPAS } IASTTypeId[] ids = getExceptionSpecification(); - for (int i = 0; i < ids.length; i++) { - if (!ids[i].accept(action)) + for (IASTTypeId id : ids) { + if (!id.accept(action)) { return false; + } } if (noexceptExpression != null && noexceptExpression != NOEXCEPT_DEFAULT) { @@ -277,6 +278,13 @@ public class CPPASTFunctionDeclarator extends CPPASTDeclarator implements ICPPAS if (trailingReturnType != null && !trailingReturnType.accept(action)) return false; + + ICPPASTVirtSpecifier[] virtSpecifiers = getVirtSpecifiers(); + for (ICPPASTVirtSpecifier virtSpecifier : virtSpecifiers) { + if (!virtSpecifier.accept(action)) { + return false; + } + } return super.postAccept(action); } @@ -298,23 +306,49 @@ public class CPPASTFunctionDeclarator extends CPPASTDeclarator implements ICPPAS @Override public boolean isOverride() { - return isOverride; + for (ICPPASTVirtSpecifier virtSpecifier : getVirtSpecifiers()) { + if (virtSpecifier.getKind() == SpecifierKind.Override) { + return true; + } + } + return false; } @Override public void setOverride(boolean value) { assertNotFrozen(); - this.isOverride = value; + // Do nothing here. Use addVirtSpecifier() instead. } @Override public boolean isFinal() { - return isFinal; + for (ICPPASTVirtSpecifier virtSpecifier : getVirtSpecifiers()) { + if (virtSpecifier.getKind() == SpecifierKind.Final) { + return true; + } + } + return false; } @Override public void setFinal(boolean value) { assertNotFrozen(); - this.isFinal = value; + // Do nothing here. Use addVirtSpecifier() instead. + } + + @Override + public ICPPASTVirtSpecifier[] getVirtSpecifiers() { + return virtSpecifiers = ArrayUtil.trim(virtSpecifiers); + } + + @Override + public void addVirtSpecifier(ICPPASTVirtSpecifier virtSpecifier) { + assertNotFrozen(); + if (virtSpecifier != null) { + assert virtSpecifiers != null; + virtSpecifiers = ArrayUtil.append(virtSpecifiers, virtSpecifier); + virtSpecifier.setParent(this); + virtSpecifier.setPropertyInParent(EXCEPTION_TYPEID); + } } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTVirtSpecifier.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTVirtSpecifier.java new file mode 100644 index 00000000000..f343b1b56c8 --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTVirtSpecifier.java @@ -0,0 +1,59 @@ +/******************************************************************************* + * Copyright (c) 2014 Nathan Ridge. + * 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 + * + * Contributors: + * Nathan Ridge - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.core.dom.parser.cpp; + +import org.eclipse.cdt.core.dom.ast.ASTVisitor; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTVirtSpecifier; +import org.eclipse.cdt.internal.core.dom.parser.ASTNode; + +public class CPPASTVirtSpecifier extends ASTNode implements ICPPASTVirtSpecifier { + private SpecifierKind fKind; + + public CPPASTVirtSpecifier(SpecifierKind kind) { + fKind = kind; + } + + @Override + public SpecifierKind getKind() { + return fKind; + } + + @Override + public ICPPASTVirtSpecifier copy() { + return copy(CopyStyle.withoutLocations); + } + + @Override + public ICPPASTVirtSpecifier copy(CopyStyle style) { + CPPASTVirtSpecifier copy = new CPPASTVirtSpecifier(fKind); + return copy(copy, style); + } + + @Override + public boolean accept(ASTVisitor action) { + if (action.shouldVisitVirtSpecifiers) { + switch (action.visit(this)) { + case ASTVisitor.PROCESS_ABORT: return false; + case ASTVisitor.PROCESS_SKIP: return true; + default: break; + } + } + + if (action.shouldVisitVirtSpecifiers) { + switch (action.leave(this)) { + case ASTVisitor.PROCESS_ABORT: return false; + case ASTVisitor.PROCESS_SKIP: return true; + default: break; + } + } + return true; + } +} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPNodeFactory.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPNodeFactory.java index 297ff7ad0c3..b0f1d433633 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPNodeFactory.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPNodeFactory.java @@ -114,6 +114,8 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTypeTransformationSpecifier; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTUnaryExpression; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTUsingDeclaration; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTUsingDirective; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTVirtSpecifier; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTVirtSpecifier.SpecifierKind; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTVisibilityLabel; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTWhileStatement; import org.eclipse.cdt.core.dom.ast.cpp.ICPPNodeFactory; @@ -774,6 +776,11 @@ public class CPPNodeFactory extends NodeFactory implements ICPPNodeFactory { return new CPPASTVisibilityLabel(visibility); } + @Override + public ICPPASTVirtSpecifier newVirtSpecifier(SpecifierKind kind) { + return new CPPASTVirtSpecifier(kind); + } + @Override public ICPPASTWhileStatement newWhileStatement() { return new CPPASTWhileStatement(); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/GNUCPPSourceParser.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/GNUCPPSourceParser.java index d098371ce4a..2833987f775 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/GNUCPPSourceParser.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/GNUCPPSourceParser.java @@ -96,6 +96,8 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTIfStatement; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTInitializerList; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTLambdaExpression; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTLambdaExpression.CaptureDefault; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTVirtSpecifier; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTVirtSpecifier.SpecifierKind; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTLinkageSpecification; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTLiteralExpression; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTName; @@ -3621,10 +3623,14 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser { char[] tokenImage = token.getCharImage(); if (Arrays.equals(Keywords.cOVERRIDE, tokenImage)) { consume(); - typeRelevantDtor.setOverride(true); + ICPPASTVirtSpecifier spec = nodeFactory.newVirtSpecifier(SpecifierKind.Override); + setRange(spec, token.getOffset(), token.getOffset() + token.getLength()); + typeRelevantDtor.addVirtSpecifier(spec); } else if (Arrays.equals(Keywords.cFINAL, tokenImage)) { consume(); - typeRelevantDtor.setFinal(true); + ICPPASTVirtSpecifier spec = nodeFactory.newVirtSpecifier(SpecifierKind.Final); + setRange(spec, token.getOffset(), token.getOffset() + token.getLength()); + typeRelevantDtor.addVirtSpecifier(spec); } else { break; } diff --git a/core/org.eclipse.cdt.ui.tests/resources/semanticHighlighting/SHTest.cpp b/core/org.eclipse.cdt.ui.tests/resources/semanticHighlighting/SHTest.cpp index 31f83eaab1c..8d1cf8637f7 100644 --- a/core/org.eclipse.cdt.ui.tests/resources/semanticHighlighting/SHTest.cpp +++ b/core/org.eclipse.cdt.ui.tests/resources/semanticHighlighting/SHTest.cpp @@ -151,3 +151,11 @@ template< template class U > class myClass {}; void g() { extern int globalVariable; // declared as global near top } + +//http://bugs.eclipse.org/399149 +class C { + void finalMethod() final; + void overrideMethod() override; + + int final; // ordinary field, happens to be named 'final' +}; diff --git a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/SemanticHighlightingTest.java b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/SemanticHighlightingTest.java index 0011a850ae1..d69427addc5 100644 --- a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/SemanticHighlightingTest.java +++ b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/SemanticHighlightingTest.java @@ -16,6 +16,8 @@ import junit.framework.TestSuite; import org.eclipse.jface.text.Position; +import org.eclipse.cdt.ui.text.ICColorConstants; + import org.eclipse.cdt.internal.ui.editor.SemanticHighlightings; /** @@ -79,6 +81,7 @@ public class SemanticHighlightingTest extends AbstractSemanticHighlightingTest { createPosition(122, 20, 15), createPosition(126, 11, 10), createPosition(126, 28, 11), + createPosition(159, 8, 5), }; if (PRINT_POSITIONS) System.out.println(toString(actual)); assertEqualPositions(expected, actual); @@ -100,6 +103,8 @@ public class SemanticHighlightingTest extends AbstractSemanticHighlightingTest { createPosition(108, 4, 26), createPosition(112, 4, 25), createPosition(117, 4, 32), + createPosition(156, 9, 11), + createPosition(157, 9, 14), }; if (PRINT_POSITIONS) System.out.println(toString(actual)); assertEqualPositions(expected, actual); @@ -122,6 +127,8 @@ public class SemanticHighlightingTest extends AbstractSemanticHighlightingTest { createPosition(117, 4, 32), createPosition(122, 4, 15), createPosition(130, 13, 9), + createPosition(156, 9, 11), + createPosition(157, 9, 14), }; Position[] actual= getSemanticHighlightingPositions(); if (PRINT_POSITIONS) System.out.println(toString(actual)); @@ -258,6 +265,7 @@ public class SemanticHighlightingTest extends AbstractSemanticHighlightingTest { createPosition(120, 4, 8), createPosition(129, 4, 8), createPosition(147, 42, 7), + createPosition(155, 6, 1), }; if (PRINT_POSITIONS) System.out.println(toString(actual)); assertEqualPositions(expected, actual); @@ -422,4 +430,15 @@ public class SemanticHighlightingTest extends AbstractSemanticHighlightingTest { if (PRINT_POSITIONS) System.out.println(toString(actual)); assertEqualPositions(expected, actual); } + + public void testContextSensitiveKeywordHighlighting() throws Exception { + setUpSemanticHighlighting(ICColorConstants.C_KEYWORD); + Position[] actual= getSemanticHighlightingPositions(); + Position[] expected= new Position[] { + createPosition(156, 23, 5), + createPosition(157, 26, 8), + }; + if (PRINT_POSITIONS) System.out.println(toString(actual)); + assertEqualPositions(expected, actual); + } } diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/ContributedSemanticHighlighting.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/ContributedSemanticHighlighting.java index ada16913806..576ec8dc202 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/ContributedSemanticHighlighting.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/ContributedSemanticHighlighting.java @@ -29,7 +29,7 @@ import org.eclipse.cdt.ui.CUIPlugin; import org.eclipse.cdt.ui.text.ISemanticHighlighter; import org.eclipse.cdt.ui.text.ISemanticToken; -public class ContributedSemanticHighlighting extends SemanticHighlighting { +public class ContributedSemanticHighlighting extends SemanticHighlightingWithOwnPreference { /** * The configuration element needs to be cached until the class is instantiated. Instantiation is deferred diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/SemanticHighlighting.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/SemanticHighlighting.java index b6d72dc3562..569f6543b36 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/SemanticHighlighting.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/SemanticHighlighting.java @@ -12,11 +12,6 @@ *******************************************************************************/ package org.eclipse.cdt.internal.ui.editor; -import org.eclipse.jface.resource.ColorRegistry; -import org.eclipse.swt.graphics.RGB; -import org.eclipse.ui.PlatformUI; - -import org.eclipse.cdt.ui.CUIPlugin; import org.eclipse.cdt.ui.text.ISemanticToken; /** @@ -30,59 +25,12 @@ public abstract class SemanticHighlighting { * @return the preference key, will be augmented by a prefix and a suffix for each preference */ public abstract String getPreferenceKey(); - + /** - * @return the default default text color - * @since 5.4 - */ - public abstract RGB getDefaultDefaultTextColor(); - - /** - * @return the default text color - */ - public RGB getDefaultTextColor() { - return findRGB(getThemeColorKey(), getDefaultDefaultTextColor()); - } - - /** - * @return true if the text attribute bold is set by default - */ - public boolean isBoldByDefault() { - return false; - } - - /** - * @return true if the text attribute italic is set by default - */ - public boolean isItalicByDefault() { - return false; - } - - /** - * @return true if the text attribute strikethrough is set by default - */ - public boolean isStrikethroughByDefault() { - return false; - } - - /** - * @return true if the text attribute underline is set by default - * @since 3.1 - */ - public boolean isUnderlineByDefault() { - return false; - } - - /** - * @return true if the text attribute italic is enabled by default + * @return true if the highlighting is enabled by default */ public abstract boolean isEnabledByDefault(); - /** - * @return the display name - */ - public abstract String getDisplayName(); - /** * Indicates that the highlighting needs to visit implicit names * (e.g. overloaded operators) @@ -102,27 +50,4 @@ public abstract class SemanticHighlighting { * @return true iff the semantic highlighting consumes the semantic token */ public abstract boolean consumes(ISemanticToken token); - - private String getThemeColorKey() { - return CUIPlugin.PLUGIN_ID + "." + getPreferenceKey() + "Highlighting"; //$NON-NLS-1$//$NON-NLS-2$ - } - - /** - * Returns the RGB for the given key in the given color registry. - * - * @param key the key for the constant in the registry - * @param defaultRGB the default RGB if no entry is found - * @return RGB the RGB - * @since 5.4 - */ - private static RGB findRGB(String key, RGB defaultRGB) { - if (!PlatformUI.isWorkbenchRunning()) - return defaultRGB; - - ColorRegistry registry= PlatformUI.getWorkbench().getThemeManager().getCurrentTheme().getColorRegistry(); - RGB rgb= registry.getRGB(key); - if (rgb != null) - return rgb; - return defaultRGB; - } } diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/SemanticHighlightingReconciler.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/SemanticHighlightingReconciler.java index 15c7b4f6f1a..6a30f4aa31c 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/SemanticHighlightingReconciler.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/SemanticHighlightingReconciler.java @@ -41,6 +41,7 @@ import org.eclipse.cdt.core.dom.ast.IASTPreprocessorMacroExpansion; import org.eclipse.cdt.core.dom.ast.IASTStatement; import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNamespaceDefinition; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTVirtSpecifier; import org.eclipse.cdt.core.model.ICElement; import org.eclipse.cdt.core.model.ILanguage; import org.eclipse.cdt.ui.CUIPlugin; @@ -75,6 +76,7 @@ public class SemanticHighlightingReconciler implements ICReconcilingListener { shouldVisitStatements= true; shouldVisitDeclarators= true; shouldVisitNamespaces= true; + shouldVisitVirtSpecifiers= true; shouldVisitImplicitNames = visitImplicitNames; shouldVisitImplicitNameAlternates = visitImplicitNames; } @@ -162,6 +164,12 @@ public class SemanticHighlightingReconciler implements ICReconcilingListener { return PROCESS_CONTINUE; } + @Override + public int visit(ICPPASTVirtSpecifier virtSpecifier) { + visitNode(virtSpecifier); + return PROCESS_CONTINUE; + } + private boolean visitNode(IASTNode node) { boolean consumed= false; fToken.update(node); diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/SemanticHighlightingWithOwnPreference.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/SemanticHighlightingWithOwnPreference.java new file mode 100644 index 00000000000..954463b4c5b --- /dev/null +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/SemanticHighlightingWithOwnPreference.java @@ -0,0 +1,98 @@ +/******************************************************************************* + * Copyright (c) 2014 Nathan Ridge. + * 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 + * + * Contributors: + * Nathan Ridge - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.ui.editor; + +import org.eclipse.jface.resource.ColorRegistry; +import org.eclipse.swt.graphics.RGB; +import org.eclipse.ui.PlatformUI; + +import org.eclipse.cdt.ui.CUIPlugin; + +/** + * A semantic highlighting which has its own preferences for specifying + * its color and style. + * + * Semantic highlightings not deriving from this class are associated + * with a syntactic highlighting, and use the color and style of that + * syntactic highlighting. + */ +public abstract class SemanticHighlightingWithOwnPreference extends SemanticHighlighting { + /** + * @return the default default text color + * @since 5.4 + */ + public abstract RGB getDefaultDefaultTextColor(); + + /** + * @return the default text color + */ + public RGB getDefaultTextColor() { + return findRGB(getThemeColorKey(), getDefaultDefaultTextColor()); + } + + /** + * @return true if the text attribute bold is set by default + */ + public boolean isBoldByDefault() { + return false; + } + + /** + * @return true if the text attribute italic is set by default + */ + public boolean isItalicByDefault() { + return false; + } + + /** + * @return true if the text attribute strikethrough is set by default + */ + public boolean isStrikethroughByDefault() { + return false; + } + + /** + * @return true if the text attribute underline is set by default + * @since 3.1 + */ + public boolean isUnderlineByDefault() { + return false; + } + + /** + * @return the display name + */ + public abstract String getDisplayName(); + + + private String getThemeColorKey() { + return CUIPlugin.PLUGIN_ID + "." + getPreferenceKey() + "Highlighting"; //$NON-NLS-1$//$NON-NLS-2$ + } + + /** + * Returns the RGB for the given key in the given color registry. + * + * @param key the key for the constant in the registry + * @param defaultRGB the default RGB if no entry is found + * @return RGB the RGB + * @since 5.4 + */ + private static RGB findRGB(String key, RGB defaultRGB) { + if (!PlatformUI.isWorkbenchRunning()) + return defaultRGB; + + ColorRegistry registry= PlatformUI.getWorkbench().getThemeManager().getCurrentTheme().getColorRegistry(); + RGB rgb= registry.getRGB(key); + if (rgb != null) + return rgb; + return defaultRGB; + } +} diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/SemanticHighlightings.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/SemanticHighlightings.java index c42dd2157af..efee625a9cd 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/SemanticHighlightings.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/SemanticHighlightings.java @@ -48,6 +48,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionDeclarator; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNameSpecifier; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTQualifiedName; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateId; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTVirtSpecifier; import org.eclipse.cdt.core.dom.ast.cpp.ICPPBlockScope; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionScope; @@ -62,6 +63,7 @@ import org.eclipse.cdt.core.index.IIndexName; import org.eclipse.cdt.core.parser.util.CharArrayUtils; import org.eclipse.cdt.ui.CUIPlugin; import org.eclipse.cdt.ui.PreferenceConstants; +import org.eclipse.cdt.ui.text.ICColorConstants; import org.eclipse.cdt.ui.text.ISemanticToken; import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPUnknownBinding; @@ -190,8 +192,7 @@ public class SemanticHighlightings { * A named preference part that controls the highlighting of operators that have been overloaded. */ public static final String OVERLOADED_OPERATOR= "overloadedOperator"; //$NON-NLS-1$ - - + /** Init debugging mode */ private static final boolean DEBUG= "true".equalsIgnoreCase(Platform.getDebugOption("org.eclipse.cdt.ui/debug/SemanticHighlighting")); //$NON-NLS-1$//$NON-NLS-2$ @@ -203,7 +204,7 @@ public class SemanticHighlightings { /** * Semantic highlighting for static fields. */ - private static final class StaticFieldHighlighting extends SemanticHighlighting { + private static final class StaticFieldHighlighting extends SemanticHighlightingWithOwnPreference { @Override public String getPreferenceKey() { return STATIC_FIELD; @@ -254,7 +255,7 @@ public class SemanticHighlightings { /** * Semantic highlighting for fields. */ - private static final class FieldHighlighting extends SemanticHighlighting { + private static final class FieldHighlighting extends SemanticHighlightingWithOwnPreference { @Override public String getPreferenceKey() { return FIELD; @@ -305,7 +306,7 @@ public class SemanticHighlightings { /** * Semantic highlighting for method declarations. */ - private static final class MethodDeclarationHighlighting extends SemanticHighlighting { + private static final class MethodDeclarationHighlighting extends SemanticHighlightingWithOwnPreference { @Override public String getPreferenceKey() { return METHOD_DECLARATION; @@ -382,7 +383,7 @@ public class SemanticHighlightings { /** * Semantic highlighting for static method invocations. */ - private static final class StaticMethodInvocationHighlighting extends SemanticHighlighting { + private static final class StaticMethodInvocationHighlighting extends SemanticHighlightingWithOwnPreference { @Override public String getPreferenceKey() { return STATIC_METHOD_INVOCATION; @@ -436,7 +437,7 @@ public class SemanticHighlightings { /** * Semantic highlighting for methods. */ - private static final class MethodHighlighting extends SemanticHighlighting { + private static final class MethodHighlighting extends SemanticHighlightingWithOwnPreference { @Override public String getPreferenceKey() { return METHOD; @@ -489,7 +490,7 @@ public class SemanticHighlightings { /** * Semantic highlighting for function declarations. */ - private static final class FunctionDeclarationHighlighting extends SemanticHighlighting { + private static final class FunctionDeclarationHighlighting extends SemanticHighlightingWithOwnPreference { @Override public String getPreferenceKey() { return FUNCTION_DECLARATION; @@ -560,7 +561,7 @@ public class SemanticHighlightings { /** * Semantic highlighting for functions. */ - private static final class FunctionHighlighting extends SemanticHighlighting { + private static final class FunctionHighlighting extends SemanticHighlightingWithOwnPreference { @Override public String getPreferenceKey() { return FUNCTION; @@ -613,7 +614,7 @@ public class SemanticHighlightings { /** * Semantic highlighting for local variable declarations. */ - private static final class LocalVariableDeclarationHighlighting extends SemanticHighlighting { + private static final class LocalVariableDeclarationHighlighting extends SemanticHighlightingWithOwnPreference { @Override public String getPreferenceKey() { return LOCAL_VARIABLE_DECLARATION; @@ -668,7 +669,7 @@ public class SemanticHighlightings { /** * Semantic highlighting for local variables. */ - private static final class LocalVariableHighlighting extends SemanticHighlighting { + private static final class LocalVariableHighlighting extends SemanticHighlightingWithOwnPreference { @Override public String getPreferenceKey() { return LOCAL_VARIABLE; @@ -749,7 +750,7 @@ public class SemanticHighlightings { /** * Semantic highlighting for global variables. */ - private static final class GlobalVariableHighlighting extends SemanticHighlighting { + private static final class GlobalVariableHighlighting extends SemanticHighlightingWithOwnPreference { @Override public String getPreferenceKey() { return GLOBAL_VARIABLE; @@ -806,7 +807,7 @@ public class SemanticHighlightings { /** * Semantic highlighting for parameter variables. */ - private static final class ParameterVariableHighlighting extends SemanticHighlighting { + private static final class ParameterVariableHighlighting extends SemanticHighlightingWithOwnPreference { @Override public String getPreferenceKey() { return PARAMETER_VARIABLE; @@ -850,7 +851,7 @@ public class SemanticHighlightings { /** * Semantic highlighting for template parameters. */ - private static final class TemplateParameterHighlighting extends SemanticHighlighting { + private static final class TemplateParameterHighlighting extends SemanticHighlightingWithOwnPreference { @Override public String getPreferenceKey() { return TEMPLATE_PARAMETER; @@ -897,7 +898,7 @@ public class SemanticHighlightings { /** * Semantic highlighting for classes. */ - private static final class ClassHighlighting extends SemanticHighlighting { + private static final class ClassHighlighting extends SemanticHighlightingWithOwnPreference { @Override public String getPreferenceKey() { return CLASS; @@ -947,7 +948,7 @@ public class SemanticHighlightings { /** * Semantic highlighting for enums. */ - private static final class EnumHighlighting extends SemanticHighlighting { + private static final class EnumHighlighting extends SemanticHighlightingWithOwnPreference { @Override public String getPreferenceKey() { return ENUM; @@ -994,7 +995,7 @@ public class SemanticHighlightings { /** * Semantic highlighting for macro references. */ - private static final class MacroReferenceHighlighting extends SemanticHighlighting { + private static final class MacroReferenceHighlighting extends SemanticHighlightingWithOwnPreference { @Override public String getPreferenceKey() { return MACRO_REFERENCE; @@ -1041,7 +1042,7 @@ public class SemanticHighlightings { /** * Semantic highlighting for macro definitions. */ - private static final class MacroDefinitionHighlighting extends SemanticHighlighting { + private static final class MacroDefinitionHighlighting extends SemanticHighlightingWithOwnPreference { @Override public String getPreferenceKey() { return MACRO_DEFINITION; @@ -1088,7 +1089,7 @@ public class SemanticHighlightings { /** * Semantic highlighting for typedefs. */ - private static final class TypedefHighlighting extends SemanticHighlighting { + private static final class TypedefHighlighting extends SemanticHighlightingWithOwnPreference { @Override public String getPreferenceKey() { return TYPEDEF; @@ -1139,7 +1140,7 @@ public class SemanticHighlightings { /** * Semantic highlighting for namespaces. */ - private static final class NamespaceHighlighting extends SemanticHighlighting { + private static final class NamespaceHighlighting extends SemanticHighlightingWithOwnPreference { @Override public String getPreferenceKey() { return NAMESPACE; @@ -1183,7 +1184,7 @@ public class SemanticHighlightings { /** * Semantic highlighting for labels. */ - private static final class LabelHighlighting extends SemanticHighlighting { + private static final class LabelHighlighting extends SemanticHighlightingWithOwnPreference { @Override public String getPreferenceKey() { return LABEL; @@ -1227,7 +1228,7 @@ public class SemanticHighlightings { /** * Semantic highlighting for enumerators. */ - private static final class EnumeratorHighlighting extends SemanticHighlighting { + private static final class EnumeratorHighlighting extends SemanticHighlightingWithOwnPreference { @Override public String getPreferenceKey() { return ENUMERATOR; @@ -1278,7 +1279,7 @@ public class SemanticHighlightings { /** * Semantic highlighting for problems. */ - private static final class ProblemHighlighting extends SemanticHighlighting { + private static final class ProblemHighlighting extends SemanticHighlightingWithOwnPreference { @Override public String getPreferenceKey() { return PROBLEM; @@ -1340,7 +1341,7 @@ public class SemanticHighlightings { /** * Semantic highlighting for external SDK references. */ - private static final class ExternalSDKHighlighting extends SemanticHighlighting { + private static final class ExternalSDKHighlighting extends SemanticHighlightingWithOwnPreference { @Override public String getPreferenceKey() { return EXTERNAL_SDK; @@ -1429,7 +1430,7 @@ public class SemanticHighlightings { /** * Semantic highlighting for functions. */ - private static final class OverloadedOperatorHighlighting extends SemanticHighlighting { + private static final class OverloadedOperatorHighlighting extends SemanticHighlightingWithOwnPreference { @Override public String getPreferenceKey() { return OVERLOADED_OPERATOR; @@ -1491,7 +1492,53 @@ public class SemanticHighlightings { return false; } } + + /** + * Semantic highlighting for context-sensitive keywords. + * + * This does not get its own color and style; rather, it uses + * the color and style of the 'Keyword' syntactic highlighting. + */ + private static final class ContextSensitiveKeywordHighlighting extends SemanticHighlighting { + @Override + public String getPreferenceKey() { + return ICColorConstants.C_KEYWORD; + } + + @Override + public boolean isEnabledByDefault() { + return true; + } + @Override + public boolean requiresImplicitNames() { + return false; + } + + @Override + public boolean consumes(ISemanticToken token) { + // Currently the only context-sensitive keywords are 'final' + // and 'override', both of which are virt-specifiers at the + // end of a method declaration. + return token.getNode() instanceof ICPPASTVirtSpecifier; + } + } + + // Note on the get___PreferenceKey() functions below: + // - For semantic highlightings deriving from SemanticHighlightingWithOwnPreference, + // these functions return keys for accessing the highlighting's own preferences. + // - For semantic highlightings not deriving from SemanticHighlightingWithOwnPreference, + // their getPreferenceKey() returns the preference key for a corresponding syntactic + // highlighting, and these functions build preference keys for specific preferences + // (e.g. color) based on that. + // - getEnabledPreferenceKey() is special in that there is no corresponding preference + // for synactic highlightings (they are always enabled), but we need to allow all + // semantic highlightings to be disabled for testing purposes, so we build a preference + // key using the naming scheme for semantic preferences for all semantic highlightings. + // From a user's perspective, semantic highlightings not deriving from + // SemanticHighlightingWithOwnPreference are still always enabled because there is no + // way to disable them in the UI. + /** * A named preference that controls the given semantic highlighting's color. * @@ -1499,7 +1546,11 @@ public class SemanticHighlightings { * @return the color preference key */ public static String getColorPreferenceKey(SemanticHighlighting semanticHighlighting) { - return PreferenceConstants.EDITOR_SEMANTIC_HIGHLIGHTING_PREFIX + semanticHighlighting.getPreferenceKey() + PreferenceConstants.EDITOR_SEMANTIC_HIGHLIGHTING_COLOR_SUFFIX; + if (semanticHighlighting instanceof SemanticHighlightingWithOwnPreference) { + return PreferenceConstants.EDITOR_SEMANTIC_HIGHLIGHTING_PREFIX + semanticHighlighting.getPreferenceKey() + PreferenceConstants.EDITOR_SEMANTIC_HIGHLIGHTING_COLOR_SUFFIX; + } else { + return semanticHighlighting.getPreferenceKey(); + } } /** @@ -1509,7 +1560,11 @@ public class SemanticHighlightings { * @return the bold preference key */ public static String getBoldPreferenceKey(SemanticHighlighting semanticHighlighting) { - return PreferenceConstants.EDITOR_SEMANTIC_HIGHLIGHTING_PREFIX + semanticHighlighting.getPreferenceKey() + PreferenceConstants.EDITOR_SEMANTIC_HIGHLIGHTING_BOLD_SUFFIX; + if (semanticHighlighting instanceof SemanticHighlightingWithOwnPreference) { + return PreferenceConstants.EDITOR_SEMANTIC_HIGHLIGHTING_PREFIX + semanticHighlighting.getPreferenceKey() + PreferenceConstants.EDITOR_SEMANTIC_HIGHLIGHTING_BOLD_SUFFIX; + } else { + return semanticHighlighting.getPreferenceKey() + PreferenceConstants.EDITOR_BOLD_SUFFIX; + } } /** @@ -1519,7 +1574,11 @@ public class SemanticHighlightings { * @return the italic preference key */ public static String getItalicPreferenceKey(SemanticHighlighting semanticHighlighting) { - return PreferenceConstants.EDITOR_SEMANTIC_HIGHLIGHTING_PREFIX + semanticHighlighting.getPreferenceKey() + PreferenceConstants.EDITOR_SEMANTIC_HIGHLIGHTING_ITALIC_SUFFIX; + if (semanticHighlighting instanceof SemanticHighlightingWithOwnPreference) { + return PreferenceConstants.EDITOR_SEMANTIC_HIGHLIGHTING_PREFIX + semanticHighlighting.getPreferenceKey() + PreferenceConstants.EDITOR_SEMANTIC_HIGHLIGHTING_ITALIC_SUFFIX; + } else { + return semanticHighlighting.getPreferenceKey() + PreferenceConstants.EDITOR_ITALIC_SUFFIX; + } } /** @@ -1529,7 +1588,11 @@ public class SemanticHighlightings { * @return the strikethrough preference key */ public static String getStrikethroughPreferenceKey(SemanticHighlighting semanticHighlighting) { - return PreferenceConstants.EDITOR_SEMANTIC_HIGHLIGHTING_PREFIX + semanticHighlighting.getPreferenceKey() + PreferenceConstants.EDITOR_SEMANTIC_HIGHLIGHTING_STRIKETHROUGH_SUFFIX; + if (semanticHighlighting instanceof SemanticHighlightingWithOwnPreference) { + return PreferenceConstants.EDITOR_SEMANTIC_HIGHLIGHTING_PREFIX + semanticHighlighting.getPreferenceKey() + PreferenceConstants.EDITOR_SEMANTIC_HIGHLIGHTING_STRIKETHROUGH_SUFFIX; + } else { + return semanticHighlighting.getPreferenceKey() + PreferenceConstants.EDITOR_STRIKETHROUGH_SUFFIX; + } } /** @@ -1539,7 +1602,11 @@ public class SemanticHighlightings { * @return the underline preference key */ public static String getUnderlinePreferenceKey(SemanticHighlighting semanticHighlighting) { - return PreferenceConstants.EDITOR_SEMANTIC_HIGHLIGHTING_PREFIX + semanticHighlighting.getPreferenceKey() + PreferenceConstants.EDITOR_SEMANTIC_HIGHLIGHTING_UNDERLINE_SUFFIX; + if (semanticHighlighting instanceof SemanticHighlightingWithOwnPreference) { + return PreferenceConstants.EDITOR_SEMANTIC_HIGHLIGHTING_PREFIX + semanticHighlighting.getPreferenceKey() + PreferenceConstants.EDITOR_SEMANTIC_HIGHLIGHTING_UNDERLINE_SUFFIX; + } else { + return semanticHighlighting.getPreferenceKey() + PreferenceConstants.EDITOR_UNDERLINE_SUFFIX; + } } /** @@ -1616,6 +1683,7 @@ public class SemanticHighlightings { highlightings.put(new Key(210), new NamespaceHighlighting()); highlightings.put(new Key(220), new LabelHighlighting()); highlightings.put(new Key(230), new EnumeratorHighlighting()); + highlightings.put(new Key(240), new ContextSensitiveKeywordHighlighting()); } private static final String ExtensionPoint = "semanticHighlighting"; //$NON-NLS-1$ @@ -1665,11 +1733,14 @@ public class SemanticHighlightings { SemanticHighlighting[] semanticHighlightings= getSemanticHighlightings(); for (SemanticHighlighting semanticHighlighting : semanticHighlightings) { store.setDefault(SemanticHighlightings.getEnabledPreferenceKey(semanticHighlighting), DEBUG || semanticHighlighting.isEnabledByDefault()); - PreferenceConverter.setDefault(store, SemanticHighlightings.getColorPreferenceKey(semanticHighlighting), semanticHighlighting.getDefaultTextColor()); - store.setDefault(SemanticHighlightings.getBoldPreferenceKey(semanticHighlighting), semanticHighlighting.isBoldByDefault()); - store.setDefault(SemanticHighlightings.getItalicPreferenceKey(semanticHighlighting), semanticHighlighting.isItalicByDefault()); - store.setDefault(SemanticHighlightings.getStrikethroughPreferenceKey(semanticHighlighting), semanticHighlighting.isStrikethroughByDefault()); - store.setDefault(SemanticHighlightings.getUnderlinePreferenceKey(semanticHighlighting), DEBUG || semanticHighlighting.isUnderlineByDefault()); + if (semanticHighlighting instanceof SemanticHighlightingWithOwnPreference) { + SemanticHighlightingWithOwnPreference highlighting = (SemanticHighlightingWithOwnPreference) semanticHighlighting; + PreferenceConverter.setDefault(store, SemanticHighlightings.getColorPreferenceKey(highlighting), highlighting.getDefaultTextColor()); + store.setDefault(SemanticHighlightings.getBoldPreferenceKey(highlighting), highlighting.isBoldByDefault()); + store.setDefault(SemanticHighlightings.getItalicPreferenceKey(highlighting), highlighting.isItalicByDefault()); + store.setDefault(SemanticHighlightings.getStrikethroughPreferenceKey(highlighting), highlighting.isStrikethroughByDefault()); + store.setDefault(SemanticHighlightings.getUnderlinePreferenceKey(highlighting), DEBUG || highlighting.isUnderlineByDefault()); + } } } diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/preferences/CEditorColoringConfigurationBlock.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/preferences/CEditorColoringConfigurationBlock.java index 96c64d82e3a..c2db7719c08 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/preferences/CEditorColoringConfigurationBlock.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/preferences/CEditorColoringConfigurationBlock.java @@ -70,6 +70,7 @@ import org.eclipse.cdt.internal.ui.editor.CSourceViewer; import org.eclipse.cdt.internal.ui.editor.SemanticHighlighting; import org.eclipse.cdt.internal.ui.editor.SemanticHighlightingManager; import org.eclipse.cdt.internal.ui.editor.SemanticHighlightingManager.HighlightedRange; +import org.eclipse.cdt.internal.ui.editor.SemanticHighlightingWithOwnPreference; import org.eclipse.cdt.internal.ui.editor.SemanticHighlightings; import org.eclipse.cdt.internal.ui.text.SimpleCSourceViewerConfiguration; import org.eclipse.cdt.internal.ui.text.util.CColorManager; @@ -375,17 +376,21 @@ class CEditorColoringConfigurationBlock extends AbstractConfigurationBlock { element[1] + UNDERLINE)); SemanticHighlighting[] semanticHighlightings= SemanticHighlightings.getSemanticHighlightings(); - for (SemanticHighlighting semanticHighlighting : semanticHighlightings) - fListModel.add( - new SemanticHighlightingColorListItem( - semanticHighlighting.getDisplayName(), - SemanticHighlightings.getColorPreferenceKey(semanticHighlighting), - SemanticHighlightings.getBoldPreferenceKey(semanticHighlighting), - SemanticHighlightings.getItalicPreferenceKey(semanticHighlighting), - SemanticHighlightings.getStrikethroughPreferenceKey(semanticHighlighting), - SemanticHighlightings.getUnderlinePreferenceKey(semanticHighlighting), - SemanticHighlightings.getEnabledPreferenceKey(semanticHighlighting) - )); + for (SemanticHighlighting semanticHighlighting : semanticHighlightings) { + if (semanticHighlighting instanceof SemanticHighlightingWithOwnPreference) { + SemanticHighlightingWithOwnPreference highlighting = (SemanticHighlightingWithOwnPreference) semanticHighlighting; + fListModel.add( + new SemanticHighlightingColorListItem( + highlighting.getDisplayName(), + SemanticHighlightings.getColorPreferenceKey(highlighting), + SemanticHighlightings.getBoldPreferenceKey(highlighting), + SemanticHighlightings.getItalicPreferenceKey(highlighting), + SemanticHighlightings.getStrikethroughPreferenceKey(highlighting), + SemanticHighlightings.getUnderlinePreferenceKey(highlighting), + SemanticHighlightings.getEnabledPreferenceKey(highlighting) + )); + } + } store.addKeys(createOverlayStoreKeys()); } @@ -872,6 +877,7 @@ class CEditorColoringConfigurationBlock extends AbstractConfigurationBlock { * @return the hard coded previewer ranges */ private SemanticHighlightingManager.HighlightedRange[][] createPreviewerRanges() { + // TODO(nathanridge): It would be nicer to actually parse the previewed code. return new SemanticHighlightingManager.HighlightedRange[][] { { createHighlightedRange( 2, 8, 5, SemanticHighlightings.MACRO_DEFINITION) }, { createHighlightedRange( 3, 16, 3, SemanticHighlightings.NAMESPACE) }, @@ -882,8 +888,8 @@ class CEditorColoringConfigurationBlock extends AbstractConfigurationBlock { { createHighlightedRange( 7, 6, 9, SemanticHighlightings.PARAMETER_VARIABLE) }, { createHighlightedRange( 7, 22, 7, SemanticHighlightings.EXTERNAL_SDK), createHighlightedRange( 7, 22, 7, SemanticHighlightings.FUNCTION) }, { createHighlightedRange( 7, 30, 6, SemanticHighlightings.GLOBAL_VARIABLE) }, - { createHighlightedRange( 8, 2, 4, SemanticHighlightings.GLOBAL_VARIABLE) }, - { createHighlightedRange( 8, 7, 2, SemanticHighlightings.OVERLOADED_OPERATOR) }, + { createHighlightedRange( 8, 2, 4, SemanticHighlightings.GLOBAL_VARIABLE) }, + { createHighlightedRange( 8, 7, 2, SemanticHighlightings.OVERLOADED_OPERATOR) }, { createHighlightedRange( 9, 9, 9, SemanticHighlightings.PARAMETER_VARIABLE) }, { createHighlightedRange(11, 6, 7, SemanticHighlightings.CLASS) }, { createHighlightedRange(13, 7, 6, SemanticHighlightings.ENUM) },