1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-04-29 19:45:01 +02:00

Patch for Victor Mozgin.

Initial pass at Task Bar/IProblem support.
This commit is contained in:
John Camelon 2003-06-28 19:48:12 +00:00
parent b628cfb34b
commit c4df8f4e6f
61 changed files with 4770 additions and 256 deletions

View file

@ -20,7 +20,7 @@ public interface ICModelMarker {
/** /**
* C model problem marker type (value <code>"org.eclipse.cdt.core.problem"</code>). * C model problem marker type (value <code>"org.eclipse.cdt.core.problem"</code>).
* This can be used to recognize those markers in the workspace that flag problems * This can be used to recognize those markers in the workspace that flag problems
* detected by the C ompilers. * detected by the C compilers.
*/ */
public static final String C_MODEL_PROBLEM_MARKER = CCorePlugin.PLUGIN_ID + ".problem"; //$NON-NLS-1$ public static final String C_MODEL_PROBLEM_MARKER = CCorePlugin.PLUGIN_ID + ".problem"; //$NON-NLS-1$
@ -30,6 +30,15 @@ public interface ICModelMarker {
* itself if it can be found. * itself if it can be found.
*/ */
public static final String C_MODEL_MARKER_VARIABLE = "problem.variable"; //$NON-NLS-1$ public static final String C_MODEL_MARKER_VARIABLE = "problem.variable"; //$NON-NLS-1$
/**
* C model task marker type (value <code>"org.eclipse.cdt.core.task"</code>).
* This can be used to recognize task markers in the workspace that correspond to tasks
* specified in C/C++ source comments and detected during translation (for example, 'TO-DO: ...').
* Tasks are identified by a task tag, which can be customized through <code>CCorePlugin</code>
* option <code>"org.eclipse.cdt.core.translation.taskTag"</code>.
*/
public static final String TASK_MARKER = CCorePlugin.PLUGIN_ID + ".task"; //$NON-NLS-1$
} }

View file

@ -8,6 +8,8 @@ package org.eclipse.cdt.core.model;
import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IPath;
import java.util.Map;
/** /**
* A C project represents a view of a project resource in terms of C * A C project represents a view of a project resource in terms of C
* elements such as , ICContainer, ITranslationUnit .... * elements such as , ICContainer, ITranslationUnit ....
@ -51,4 +53,59 @@ public interface ICProject extends ICContainer {
* @return IProject * @return IProject
*/ */
IProject getProject(); IProject getProject();
/**
* Helper method for returning one option value only. Equivalent to <code>(String)this.getOptions(inheritCCoreOptions).get(optionName)</code>
* Note that it may answer <code>null</code> if this option does not exist, or if there is no custom value for it.
* <p>
* For a complete description of the configurable options, see <code>CCorePlugin#getDefaultOptions</code>.
* </p>
*
* @param optionName the name of an option
* @param inheritCCoreOptions - boolean indicating whether CCorePlugin options should be inherited as well
* @return the String value of a given option
* @see CCorePlugin#getDefaultOptions
*/
String getOption(String optionName, boolean inheritCCoreOptions);
/**
* Returns the table of the current custom options for this project. Projects remember their custom options,
* in other words, only the options different from the the CCorePlugin global options for the workspace.
* A boolean argument allows to directly merge the project options with global ones from <code>CCorePlugin</code>.
* <p>
* For a complete description of the configurable options, see <code>CCorePlugin#getDefaultOptions</code>.
* </p>
*
* @param inheritCCoreOptions - boolean indicating whether CCorePlugin options should be inherited as well
* @return table of current settings of all options
* (key type: <code>String</code>; value type: <code>String</code>)
* @see CCorePlugin#getDefaultOptions
*/
Map getOptions(boolean inheritCCoreOptions);
/**
* Helper method for setting one option value only. Equivalent to <code>Map options = this.getOptions(false); map.put(optionName, optionValue); this.setOptions(map)</code>
* <p>
* For a complete description of the configurable options, see <code>CCorePlugin#getDefaultOptions</code>.
* </p>
*
* @param optionName the name of an option
* @param optionValue the value of the option to set
* @see CCorePlugin#getDefaultOptions
*/
void setOption(String optionName, String optionValue);
/**
* Sets the project custom options. All and only the options explicitly included in the given table
* are remembered; all previous option settings are forgotten, including ones not explicitly
* mentioned.
* <p>
* For a complete description of the configurable options, see <code>CCorePlugin#getDefaultOptions</code>.
* </p>
*
* @param newOptions the new options (key type: <code>String</code>; value type: <code>String</code>),
* or <code>null</code> to flush all custom options (clients will automatically get the global CCorePlugin options).
* @see CCorePlugin#getDefaultOptions
*/
void setOptions(Map newOptions);
} }

View file

@ -17,15 +17,20 @@ import java.util.HashMap;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.HashSet;
import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.model.CoreModel; import org.eclipse.cdt.core.model.CoreModel;
import org.eclipse.cdt.core.model.ICElement; import org.eclipse.cdt.core.model.ICElement;
import org.eclipse.cdt.core.model.ICModelMarker;
import org.eclipse.cdt.core.model.INamespace; import org.eclipse.cdt.core.model.INamespace;
import org.eclipse.cdt.core.model.IParent; import org.eclipse.cdt.core.model.IParent;
import org.eclipse.cdt.core.model.IStructure; import org.eclipse.cdt.core.model.IStructure;
import org.eclipse.cdt.core.model.ITemplate; import org.eclipse.cdt.core.model.ITemplate;
import org.eclipse.cdt.core.model.ITranslationUnit; import org.eclipse.cdt.core.model.ITranslationUnit;
import org.eclipse.cdt.core.parser.ITranslationResult;
import org.eclipse.cdt.core.parser.IParser; import org.eclipse.cdt.core.parser.IParser;
import org.eclipse.cdt.core.parser.IProblem;
import org.eclipse.cdt.core.parser.ParserFactory; import org.eclipse.cdt.core.parser.ParserFactory;
import org.eclipse.cdt.core.parser.ParserMode; import org.eclipse.cdt.core.parser.ParserMode;
import org.eclipse.cdt.internal.core.dom.ArrayQualifier; import org.eclipse.cdt.internal.core.dom.ArrayQualifier;
@ -52,11 +57,20 @@ import org.eclipse.cdt.internal.core.dom.TemplateDeclaration;
import org.eclipse.cdt.internal.core.dom.TemplateParameter; import org.eclipse.cdt.internal.core.dom.TemplateParameter;
import org.eclipse.cdt.internal.core.dom.TranslationUnit; import org.eclipse.cdt.internal.core.dom.TranslationUnit;
import org.eclipse.cdt.internal.core.dom.TypeSpecifier; import org.eclipse.cdt.internal.core.dom.TypeSpecifier;
import org.eclipse.cdt.internal.core.parser.DefaultErrorHandlingPolicies;
import org.eclipse.cdt.internal.core.parser.TranslationResult;
import org.eclipse.cdt.internal.core.parser.TranslationOptions;
import org.eclipse.cdt.internal.core.parser.ITranslationResultRequestor;
import org.eclipse.cdt.internal.core.parser.Name; import org.eclipse.cdt.internal.core.parser.Name;
import org.eclipse.cdt.internal.core.parser.problem.DefaultProblemFactory;
import org.eclipse.cdt.internal.core.parser.problem.ProblemReporter;
import org.eclipse.core.resources.IMarker;
import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.CoreException;
public class CModelBuilder { public class CModelBuilder implements ITranslationResultRequestor {
protected org.eclipse.cdt.internal.core.model.TranslationUnit translationUnit; protected org.eclipse.cdt.internal.core.model.TranslationUnit translationUnit;
protected Map newElements; protected Map newElements;
@ -67,8 +81,37 @@ public class CModelBuilder {
} }
public Map parse() throws Exception { public Map parse() throws Exception {
DOMBuilder domBuilder = new DOMBuilder(); DOMBuilder domBuilder = new DOMBuilder();
IParser parser = ParserFactory.createParser(ParserFactory.createScanner( new StringReader( translationUnit.getBuffer().getContents() ), null, null, null, ParserMode.QUICK_PARSE ), domBuilder, ParserMode.QUICK_PARSE);
// create a problem reporter
Map options = null;
if (translationUnit != null && translationUnit.getCProject() != null) {
options = translationUnit.getCProject().getOptions(true);
}
TranslationOptions cOptions = new TranslationOptions(options);
ProblemReporter problemReporter = new ProblemReporter(
DefaultErrorHandlingPolicies.proceedWithAllProblems(),
cOptions,
new DefaultProblemFactory()
);
// create translation result
TranslationResult unitResult = new TranslationResult(translationUnit);
IParser parser = ParserFactory.createParser(
ParserFactory.createScanner(
new StringReader(
translationUnit.getBuffer().getContents()
),
null, null, null,
ParserMode.QUICK_PARSE,
problemReporter, unitResult
),
domBuilder,
ParserMode.QUICK_PARSE,
problemReporter, unitResult
);
if( translationUnit.getCProject() != null ) if( translationUnit.getCProject() != null )
{ {
@ -96,6 +139,9 @@ public class CModelBuilder {
npe.printStackTrace(); npe.printStackTrace();
} }
// process translation results
acceptResult(unitResult);
// For the debuglog to take place, you have to call // For the debuglog to take place, you have to call
// Util.setDebugging(true); // Util.setDebugging(true);
// Or set debug to true in the core plugin preference // Or set debug to true in the core plugin preference
@ -1009,4 +1055,100 @@ public class CModelBuilder {
return name; return name;
} }
/**
* @see ITranslatorRequestor#acceptResult(ITranslationResult)
*/
public void acceptResult(ITranslationResult result) {
ITranslationUnit translationUnit = result.getTranslationUnit();
try {
updateTasksFor(translationUnit, result); // record tasks
} catch (CoreException e) {
System.out.println("Exception while accepting parse results");
e.printStackTrace();
}
}
protected void updateTasksFor(ITranslationUnit sourceFile, ITranslationResult result) throws CoreException {
IProblem[] tasks = result.getTasks();
storeTasksFor(sourceFile, tasks);
}
protected void storeTasksFor(ITranslationUnit sourceFile, IProblem[] tasks) throws CoreException {
if (sourceFile == null) return;
if (tasks == null) tasks = new IProblem[0];
IResource resource = sourceFile.getResource();
IMarker[] existingTaskMarkers = resource.findMarkers(ICModelMarker.TASK_MARKER, false, IResource.DEPTH_ONE);
HashSet taskSet = new HashSet();
if (existingTaskMarkers != null)
for (int i=0; i<existingTaskMarkers.length; i++)
taskSet.add(existingTaskMarkers[i]);
taskLoop:
for (int i = 0, l = tasks.length; i < l; i++) {
IProblem task = tasks[i];
if (task.getID() == IProblem.Task) {
int priority = IMarker.PRIORITY_NORMAL;
String compilerPriority = task.getArguments()[2];
if (CCorePlugin.TRANSLATION_TASK_PRIORITY_HIGH.equals(compilerPriority))
priority = IMarker.PRIORITY_HIGH;
else if (CCorePlugin.TRANSLATION_TASK_PRIORITY_LOW.equals(compilerPriority))
priority = IMarker.PRIORITY_LOW;
/*
* Try to find matching markers and don't put in duplicates
*/
if ((existingTaskMarkers != null) && (existingTaskMarkers.length > 0)) {
for (int j = 0; j < existingTaskMarkers.length; j++) {
if (
(((Integer) existingTaskMarkers[j].getAttribute(IMarker.LINE_NUMBER)).intValue() == task.getSourceLineNumber())
&& (((Integer) existingTaskMarkers[j].getAttribute(IMarker.PRIORITY)).intValue() == priority)
&& (((Integer) existingTaskMarkers[j].getAttribute(IMarker.CHAR_START)).intValue() == task.getSourceStart())
&& (((Integer) existingTaskMarkers[j].getAttribute(IMarker.CHAR_END)).intValue() == task.getSourceEnd()+1)
&& (((String) existingTaskMarkers[j].getAttribute(IMarker.MESSAGE)).equals(task.getMessage()))
) {
taskSet.remove(existingTaskMarkers[j]);
continue taskLoop;
}
}
}
IMarker marker = resource.createMarker(ICModelMarker.TASK_MARKER);
marker.setAttributes(
new String[] {
IMarker.MESSAGE,
IMarker.PRIORITY,
IMarker.DONE,
IMarker.CHAR_START,
IMarker.CHAR_END,
IMarker.LINE_NUMBER,
IMarker.USER_EDITABLE,
},
new Object[] {
task.getMessage(),
new Integer(priority),
new Boolean(false),
new Integer(task.getSourceStart()),
new Integer(task.getSourceEnd() + 1),
new Integer(task.getSourceLineNumber()),
new Boolean(false),
});
}
}
// Remove all obsolete markers
Iterator setI = taskSet.iterator();
while (setI.hasNext()) {
IMarker marker = (IMarker)setI.next();
marker.delete();
}
}
} }

View file

@ -8,6 +8,7 @@ package org.eclipse.cdt.internal.core.model;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator; import java.util.Iterator;
import java.util.Map; import java.util.Map;
@ -50,6 +51,8 @@ public class CModelManager implements IResourceChangeListener {
*/ */
final CModel cModel = new CModel(); final CModel cModel = new CModel();
public static HashSet OptionNames = new HashSet(20);
/** /**
* Used to convert <code>IResourceDelta</code>s into <code>ICElementDelta</code>s. * Used to convert <code>IResourceDelta</code>s into <code>ICElementDelta</code>s.
*/ */

View file

@ -6,6 +6,10 @@ package org.eclipse.cdt.internal.core.model;
*/ */
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Iterator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import org.eclipse.cdt.core.CCorePlugin; import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.CProjectNature; import org.eclipse.cdt.core.CProjectNature;
@ -21,6 +25,8 @@ import org.eclipse.cdt.core.model.ILibraryReference;
import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Preferences;
import org.eclipse.core.runtime.QualifiedName;
public class CProject extends CContainer implements ICProject { public class CProject extends CContainer implements ICProject {
@ -40,6 +46,8 @@ public class CProject extends CContainer implements ICProject {
return getUnderlyingResource().getProject(); return getUnderlyingResource().getProject();
} }
private static final String CUSTOM_DEFAULT_OPTION_VALUE = "#\r\n\r#custom-non-empty-default-value#\r\n\r#"; //$NON-NLS-1$
public ICElement findElement(IPath path) throws CModelException { public ICElement findElement(IPath path) throws CModelException {
ICElement celem = null; ICElement celem = null;
if (path.isAbsolute()) { if (path.isAbsolute()) {
@ -92,4 +100,149 @@ public class CProject extends CContainer implements ICProject {
} }
return (ILibraryReference[])list.toArray(new ILibraryReference[0]); return (ILibraryReference[])list.toArray(new ILibraryReference[0]);
} }
/**
* @see org.eclipse.cdt.core.model.ICProject#getOption(String, boolean)
*/
public String getOption(String optionName, boolean inheritCCoreOptions) {
if (CModelManager.OptionNames.contains(optionName)) {
Preferences preferences = getPreferences();
if (preferences == null || preferences.isDefault(optionName)) {
return inheritCCoreOptions ? CCorePlugin.getOption(optionName) : null;
}
return preferences.getString(optionName).trim();
}
return null;
}
/**
* @see org.eclipse.cdt.core.model.ICProject#getOptions(boolean)
*/
public Map getOptions(boolean inheritCCoreOptions) {
// initialize to the defaults from CCorePlugin options pool
Map options = inheritCCoreOptions ? CCorePlugin.getOptions() : new HashMap(5);
Preferences preferences = getPreferences();
if (preferences == null) return options;
HashSet optionNames = CModelManager.OptionNames;
// get preferences set to their default
if (inheritCCoreOptions){
String[] defaultPropertyNames = preferences.defaultPropertyNames();
for (int i = 0; i < defaultPropertyNames.length; i++){
String propertyName = defaultPropertyNames[i];
if (optionNames.contains(propertyName)){
options.put(propertyName, preferences.getDefaultString(propertyName).trim());
}
}
}
// get custom preferences not set to their default
String[] propertyNames = preferences.propertyNames();
for (int i = 0; i < propertyNames.length; i++){
String propertyName = propertyNames[i];
if (optionNames.contains(propertyName)){
options.put(propertyName, preferences.getString(propertyName).trim());
}
}
return options;
}
/**
* @see org.eclipse.cdt.core.model.ICProject#setOption(java.lang.String, java.lang.String)
*/
public void setOption(String optionName, String optionValue) {
if (!CModelManager.OptionNames.contains(optionName)) return; // unrecognized option
Preferences preferences = getPreferences();
preferences.setDefault(optionName, CUSTOM_DEFAULT_OPTION_VALUE); // empty string isn't the default (26251)
preferences.setValue(optionName, optionValue);
savePreferences(preferences);
}
/**
* @see org.eclipse.cdt.core.model.ICProject#setOptions(Map)
*/
public void setOptions(Map newOptions)
{
Preferences preferences = new Preferences();
setPreferences(preferences); // always reset (26255)
if (newOptions != null){
Iterator keys = newOptions.keySet().iterator();
while (keys.hasNext()){
String key = (String)keys.next();
if (!CModelManager.OptionNames.contains(key)) continue; // unrecognized option
// no filtering for encoding (custom encoding for project is allowed)
String value = (String)newOptions.get(key);
preferences.setDefault(key, CUSTOM_DEFAULT_OPTION_VALUE); // empty string isn't the default (26251)
preferences.setValue(key, value);
}
}
// persist options
savePreferences(preferences);
}
/**
* Returns the project custom preference pool.
* Project preferences may include custom encoding.
*/
private Preferences getPreferences() {
Preferences preferences = new Preferences();
Iterator iter = CModelManager.OptionNames.iterator();
while (iter.hasNext()) {
String qualifiedName = (String)iter.next();
String dequalifiedName = qualifiedName.substring(CCorePlugin.PLUGIN_ID.length()+1);
String value = null;
try {
value = resource.getPersistentProperty(new QualifiedName(CCorePlugin.PLUGIN_ID, dequalifiedName));
} catch (CoreException e) {
}
if (value != null) preferences.setValue(qualifiedName, value);
}
return preferences;
}
/**
* Save project custom preferences to persistent properties
*/
private void savePreferences(Preferences preferences) {
if (preferences == null) return;
Iterator iter = CModelManager.OptionNames.iterator();
while (iter.hasNext()) {
String qualifiedName = (String)iter.next();
String dequalifiedName = qualifiedName.substring(CCorePlugin.PLUGIN_ID.length()+1);
String value = null;
try {
value = preferences.getString(qualifiedName);
if (value != null && !value.equals(preferences.getDefaultString(qualifiedName))) {
resource.setPersistentProperty(new QualifiedName(CCorePlugin.PLUGIN_ID, dequalifiedName), value);
} else {
resource.setPersistentProperty(new QualifiedName(CCorePlugin.PLUGIN_ID, dequalifiedName), null);
}
} catch (CoreException e) {
}
}
}
/*
* Set cached preferences, no preferences are saved, only info is updated
*/
private void setPreferences(Preferences preferences) {
// Do nothing
}
} }

View file

@ -2,6 +2,11 @@
Update IASTExpression. Update IASTExpression.
Move Parser.Backtrack and Parser.EndOfFile to external interface. Move Parser.Backtrack and Parser.EndOfFile to external interface.
2003-06-26 Victor Mozgin
Task tags support in C/C++ comments (initial revision).
Infrastructure to support problem reporting during translation.
Additional infrastructure for options/preferences handling.
2003-06-25 John Camelon 2003-06-25 John Camelon
Fixed bug39348 - sizeof elaborated types fail in parsing expression Fixed bug39348 - sizeof elaborated types fail in parsing expression

View file

@ -1,19 +1,148 @@
/********************************************************************** /*******************************************************************************
* Copyright (c) 2002,2003 Rational Software Corporation and others. * Copyright (c) 2000, 2003 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Common Public License v0.5 * are made available under the terms of the Common Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/cpl-v05.html * http://www.eclipse.org/legal/cpl-v10.html
* *
* Contributors: * Contributors:
* IBM Rational Software - Initial API and implementation * IBM Corporation - initial API and implementation
***********************************************************************/ *******************************************************************************/
package org.eclipse.cdt.core.parser; package org.eclipse.cdt.core.parser;
/** /**
* @author jcamelon * Description of a C/C++ problem, as detected by the translation or some of the underlying
* * technology reusing it.
* A problem provides access to:
* <ul>
* <li> its location (originating source file name, source position, line number), </li>
* <li> its message description and a predicate to check its severity (warning or error). </li>
* <li> its ID : an number identifying the very nature of this problem. All possible IDs are listed
* as constants on this interface. </li>
* </ul>
*/ */
public interface IProblem { public interface IProblem {
/**
* Answer back the original arguments recorded into the problem.
* @return the original arguments recorded into the problem
*/
String[] getArguments();
/**
* Returns the problem id
*
* @return the problem id
*/
int getID();
/**
* Answer a localized, human-readable message string which describes the problem.
*
* @return a localized, human-readable message string which describes the problem
*/
String getMessage();
/**
* Answer the file name in which the problem was found.
*
* @return the file name in which the problem was found
*/
char[] getOriginatingFileName();
/**
* Answer the end position of the problem (inclusive), or -1 if unknown.
*
* @return the end position of the problem (inclusive), or -1 if unknown
*/
int getSourceEnd();
/**
* Answer the line number in source where the problem begins.
*
* @return the line number in source where the problem begins
*/
int getSourceLineNumber();
/**
* Answer the start position of the problem (inclusive), or -1 if unknown.
*
* @return the start position of the problem (inclusive), or -1 if unknown
*/
int getSourceStart();
/**
* Checks the severity to see if the Error bit is set.
*
* @return true if the Error bit is set for the severity, false otherwise
*/
boolean isError();
/**
* Checks the severity to see if the Warning bit is not set.
*
* @return true if the Warning bit is not set for the severity, false otherwise
*/
boolean isWarning();
/**
* Set the end position of the problem (inclusive), or -1 if unknown.
* Used for shifting problem positions.
*
* @param sourceEnd the given end position
*/
void setSourceEnd(int sourceEnd);
/**
* Set the line number in source where the problem begins.
*
* @param lineNumber the given line number
*/
void setSourceLineNumber(int lineNumber);
/**
* Set the start position of the problem (inclusive), or -1 if unknown.
* Used for shifting problem positions.
*
* @param the given start position
*/
void setSourceStart(int sourceStart);
/**
* Problem Categories
* The high bits of a problem ID contains information about the category of a problem.
* For example, (problemID & TypeRelated) != 0, indicates that this problem is type related.
*
* A problem category can help to implement custom problem filters. Indeed, when numerous problems
* are listed, focusing on import related problems first might be relevant.
*
* When a problem is tagged as Internal, it means that no change other than a local source code change
* can fix the corresponding problem.
*/
int TypeRelated = 0x01000000;
int FieldRelated = 0x02000000;
int MethodRelated = 0x04000000;
int ConstructorRelated = 0x08000000;
int ImportRelated = 0x10000000;
int Internal = 0x20000000;
int Syntax = 0x40000000;
/**
* Mask to use in order to filter out the category portion of the problem ID.
*/
int IgnoreCategoriesMask = 0xFFFFFF;
/**
* Below are listed all available problem IDs. Note that this list could be augmented in the future,
* as new features are added to the C/C++ core implementation.
*/
/**
* ID reserved for referencing an internal error inside the CCorePlugin implementation which
* may be surfaced as a problem associated with the translation unit which caused it to occur.
*/
int Unclassified = 0;
// detected task
int Task = Internal + 450;
} }

View file

@ -0,0 +1,27 @@
/*
* Created on 25-Jun-2003
*
* To change the template for this generated file go to
* Window>Preferences>Java>Code Generation>Code and Comments
*/
package org.eclipse.cdt.core.parser;
/**
* @author vmozgin
*
* To change the template for this generated type comment go to
* Window>Preferences>Java>Code Generation>Code and Comments
*/
public interface IProblemReporter {
public ITranslationOptions getOptions();
public abstract void task(
String tag,
String message,
String priority,
int start,
int end,
int line,
ITranslationResult result);
}

View file

@ -0,0 +1,21 @@
/*******************************************************************************
* Copyright (c) 2000, 2003 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Common Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/cpl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.core.parser;
/**
* Implementors are valid translation contexts from which we can
* escape in case of error:
* For example: method, type or translation unit.
*/
public interface IReferenceContext {
ITranslationResult translationResult();
}

View file

@ -33,12 +33,9 @@ public interface IScanner {
public int getCount(); public int getCount();
public int getDepth(); public int getDepth();
/**
* @return
*/
public IToken nextTokenForStringizing() throws ScannerException, EndOfFile; public IToken nextTokenForStringizing() throws ScannerException, EndOfFile;
/**
* @param b
*/
public void setTokenizingMacroReplacementList(boolean b); public void setTokenizingMacroReplacementList(boolean b);
public void onParseEnd();
} }

View file

@ -24,9 +24,10 @@ public interface IScannerContext {
* *
* @param macroOffset Offset of the expanding macro * @param macroOffset Offset of the expanding macro
* @param macroLength Length of the macro identifier * @param macroLength Length of the macro identifier
* @param line Initial line counter for the context
* @return * @return
*/ */
public IScannerContext initialize(Reader r, String f, int k, IASTInclusion i, int macroOffset, int macroLength); public IScannerContext initialize(Reader r, String f, int k, IASTInclusion i, int macroOffset, int macroLength, int line);
public IScannerContext initialize(Reader r, String f, int k, IASTInclusion i); public IScannerContext initialize(Reader r, String f, int k, IASTInclusion i);
public int read() throws IOException; public int read() throws IOException;
@ -56,6 +57,12 @@ public interface IScannerContext {
*/ */
public int getRelativeOffset(); public int getRelativeOffset();
/**
* Returns current line counter.
* @return int
*/
public int getLine();
public Reader getReader(); public Reader getReader();
public int undoStackSize(); public int undoStackSize();

View file

@ -0,0 +1,35 @@
/*
* Created on 25-Jun-2003
*
* To change the template for this generated file go to
* Window>Preferences>Java>Code Generation>Code and Comments
*/
package org.eclipse.cdt.core.parser;
import java.util.Map;
/**
* @author vmozgin
*
* To change the template for this generated type comment go to
* Window>Preferences>Java>Code Generation>Code and Comments
*/
public interface ITranslationOptions {
/**
* Option IDs
*/
public static final String OPTION_TaskTags
= "org.eclipse.cdt.core.translation.taskTags"; //$NON-NLS-1$
public static final String OPTION_TaskPriorities
= "org.eclipse.cdt.core.translation.taskPriorities"; //$NON-NLS-1$
/**
* Initializing the compiler options with external settings
*/
public abstract void initialize(Map settings);
public abstract char[][] getTaskTags();
public abstract char[][] getTaskPriorities();
}

View file

@ -0,0 +1,65 @@
/*
* Created on 25-Jun-2003
*
* To change the template for this generated file go to
* Window>Preferences>Java>Code Generation>Code and Comments
*/
package org.eclipse.cdt.core.parser;
import org.eclipse.cdt.core.model.ITranslationUnit;
/**
* @author vmozgin
*
* To change the template for this generated type comment go to
* Window>Preferences>Java>Code Generation>Code and Comments
*/
public interface ITranslationResult {
public abstract IProblem[] getAllProblems();
/**
* Answer the initial translation unit corresponding to the present translation result
*/
public abstract ITranslationUnit getTranslationUnit();
/**
* Answer the initial file name
*/
public abstract char[] getFileName();
/**
* Answer the errors encountered during translation.
*/
public abstract IProblem[] getErrors();
/**
* Answer the problems (errors and warnings) encountered during translation.
*
* It is intended to be used only once all problems have been detected,
* and makes sure the problems slot as the exact size of the number of
* problems.
*/
public abstract IProblem[] getProblems();
/**
* Answer the tasks (TO-DO, ...) encountered during translation.
*
* It is intended to be used only once all problems have been detected,
* and makes sure the problems slot as the exact size of the number of
* problems.
*/
public abstract IProblem[] getTasks();
public abstract boolean hasErrors();
public abstract boolean hasProblems();
public abstract boolean hasSyntaxError();
public abstract boolean hasTasks();
public abstract boolean hasWarnings();
public abstract void record(IProblem newProblem, IReferenceContext referenceContext);
public abstract ITranslationResult tagAsAccepted();
}

View file

@ -23,6 +23,7 @@ import org.eclipse.cdt.internal.core.parser.Scanner;
import org.eclipse.cdt.internal.core.parser.ast.full.FullParseASTFactory; import org.eclipse.cdt.internal.core.parser.ast.full.FullParseASTFactory;
import org.eclipse.cdt.internal.core.parser.ast.quick.QuickParseASTFactory; import org.eclipse.cdt.internal.core.parser.ast.quick.QuickParseASTFactory;
/** /**
* @author jcamelon * @author jcamelon
* *
@ -38,25 +39,40 @@ public class ParserFactory {
} }
public static IParser createParser( IScanner scanner, IParserCallback callback, ParserMode mode ) public static IParser createParser( IScanner scanner, IParserCallback callback, ParserMode mode )
{
return createParser(scanner, callback, mode, null, null);
}
public static IParser createParser( IScanner scanner, IParserCallback callback, ParserMode mode, IProblemReporter problemReporter, ITranslationResult unitResult )
{ {
ParserMode ourMode = ( (mode == null )? ParserMode.COMPLETE_PARSE : mode ); ParserMode ourMode = ( (mode == null )? ParserMode.COMPLETE_PARSE : mode );
IParserCallback ourCallback = (( callback == null) ? new NullSourceElementRequestor() : callback ); IParserCallback ourCallback = (( callback == null) ? new NullSourceElementRequestor() : callback );
return new Parser( scanner, ourCallback, ourMode ); return new Parser( scanner, ourCallback, ourMode, problemReporter, unitResult );
} }
public static IScanner createScanner( Reader input, String fileName, Map defns, List inclusions, ParserMode mode ) public static IScanner createScanner( Reader input, String fileName, Map defns, List inclusions, ParserMode mode )
{
return createScanner(input, fileName, defns, inclusions, mode, null, null);
}
public static IScanner createScanner( Reader input, String fileName, Map defns, List inclusions, ParserMode mode, IProblemReporter problemReporter, ITranslationResult unitResult )
{ {
ParserMode ourMode = ( (mode == null )? ParserMode.COMPLETE_PARSE : mode ); ParserMode ourMode = ( (mode == null )? ParserMode.COMPLETE_PARSE : mode );
IScanner s = new Scanner( input, fileName, defns ); IScanner s = new Scanner( input, fileName, defns, problemReporter, unitResult );
s.setMode( ourMode ); s.setMode( ourMode );
s.overwriteIncludePath(inclusions); s.overwriteIncludePath(inclusions);
return s; return s;
} }
public static IPreprocessor createPreprocessor( Reader input, String fileName, Map defns, List inclusions, ParserMode mode ) public static IPreprocessor createPreprocessor( Reader input, String fileName, Map defns, List inclusions, ParserMode mode )
{
return createPreprocessor(input, fileName, defns, inclusions, mode, null, null);
}
public static IPreprocessor createPreprocessor( Reader input, String fileName, Map defns, List inclusions, ParserMode mode, IProblemReporter problemReporter, ITranslationResult unitResult )
{ {
ParserMode ourMode = ( (mode == null )? ParserMode.COMPLETE_PARSE : mode ); ParserMode ourMode = ( (mode == null )? ParserMode.COMPLETE_PARSE : mode );
IPreprocessor s = new Preprocessor( input, fileName, defns ); IPreprocessor s = new Preprocessor( input, fileName, defns, problemReporter, unitResult );
s.setMode( ourMode ); s.setMode( ourMode );
s.overwriteIncludePath(inclusions); s.overwriteIncludePath(inclusions);
return s; return s;

View file

@ -42,6 +42,8 @@ public class ContextStack {
public void updateContext(Reader reader, String filename, int type, IASTInclusion inclusion, ISourceElementRequestor requestor, int macroOffset, int macroLength) throws ScannerException public void updateContext(Reader reader, String filename, int type, IASTInclusion inclusion, ISourceElementRequestor requestor, int macroOffset, int macroLength) throws ScannerException
{ {
int startLine = 1;
// If we expand a macro within a macro, then keep offsets of the top-level one, // If we expand a macro within a macro, then keep offsets of the top-level one,
// as only the top level macro identifier is properly positioned // as only the top level macro identifier is properly positioned
if (type == IScannerContext.MACROEXPANSION) { if (type == IScannerContext.MACROEXPANSION) {
@ -49,10 +51,12 @@ public class ContextStack {
macroOffset = currentContext.getMacroOffset(); macroOffset = currentContext.getMacroOffset();
macroLength = currentContext.getMacroLength(); macroLength = currentContext.getMacroLength();
} }
startLine = currentContext.getLine();
} }
undoStack.clear(); undoStack.clear();
push( new ScannerContext().initialize(reader, filename, type, null, macroOffset, macroLength ), requestor ); push( new ScannerContext().initialize(reader, filename, type, null, macroOffset, macroLength, startLine ), requestor );
} }
protected void push( IScannerContext context, ISourceElementRequestor requestor ) throws ScannerException protected void push( IScannerContext context, ISourceElementRequestor requestor ) throws ScannerException

View file

@ -0,0 +1,78 @@
/*******************************************************************************
* Copyright (c) 2000, 2003 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Common Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/cpl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.internal.core.parser;
public class DefaultErrorHandlingPolicies {
/**
* Accumulate all problems, then exit without proceeding.
*
* Typically, the #proceedWithProblems(Problem[]) should
* show the problems.
*
*/
public static IErrorHandlingPolicy exitAfterAllProblems() {
return new IErrorHandlingPolicy() {
public boolean stopOnFirstError() {
return false;
}
public boolean proceedOnErrors(){
return false;
}
};
}
/**
* Exit without proceeding on the first problem wich appears
* to be an error.
*
*/
public static IErrorHandlingPolicy exitOnFirstError() {
return new IErrorHandlingPolicy() {
public boolean stopOnFirstError() {
return true;
}
public boolean proceedOnErrors(){
return false;
}
};
}
/**
* Proceed on the first error met.
*
*/
public static IErrorHandlingPolicy proceedOnFirstError() {
return new IErrorHandlingPolicy() {
public boolean stopOnFirstError() {
return true;
}
public boolean proceedOnErrors(){
return true;
}
};
}
/**
* Accumulate all problems, then proceed with them.
*
*/
public static IErrorHandlingPolicy proceedWithAllProblems() {
return new IErrorHandlingPolicy() {
public boolean stopOnFirstError() {
return false;
}
public boolean proceedOnErrors(){
return true;
}
};
}
}

View file

@ -0,0 +1,28 @@
/*******************************************************************************
* Copyright (c) 2000, 2003 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Common Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/cpl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.internal.core.parser;
/**
* Handler policy is responsible to answer the 2 following
* questions:
* 1. should the handler stop on first problem which appears
* to be a real error (that is, not a warning),
* 2. should it proceed once it has gathered all problems
*
* The intent is that one can supply its own policy to implement
* some interactive error handling strategy where some UI would
* display problems and ask user if he wants to proceed or not.
*/
public interface IErrorHandlingPolicy {
boolean proceedOnErrors();
boolean stopOnFirstError();
}

View file

@ -0,0 +1,41 @@
/*******************************************************************************
* Copyright (c) 2000, 2003 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Common Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/cpl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.internal.core.parser;
import org.eclipse.cdt.core.parser.IProblem;
import java.util.Locale;
/**
* Factory used during translation to build the actual problems
* which are handed back in the translation result.
*
* This allows sharing the internal problem representation with the environment.
*
* Note: The factory is responsible for computing and storing a localized error message.
*/
public interface IProblemFactory {
IProblem createProblem(
char[] originatingFileName,
int problemId,
String[] problemArguments,
String[] messageArguments, // shorter versions of the problemArguments
int severity,
int startPosition,
int endPosition,
int lineNumber);
Locale getLocale();
String getLocalizedMessage(int problemId, String[] messageArguments);
}

View file

@ -0,0 +1,24 @@
/*******************************************************************************
* Copyright (c) 2000, 2003 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Common Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/cpl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.internal.core.parser;
import org.eclipse.cdt.core.parser.ITranslationResult;
/**
* A callback interface for receiving translation results.
*/
public interface ITranslationResultRequestor {
/**
* Accept a translation result.
*/
public void acceptResult(ITranslationResult result);
}

View file

@ -13,7 +13,9 @@ import org.eclipse.cdt.core.parser.Backtrack;
import org.eclipse.cdt.core.parser.EndOfFile; import org.eclipse.cdt.core.parser.EndOfFile;
import org.eclipse.cdt.core.parser.IParser; import org.eclipse.cdt.core.parser.IParser;
import org.eclipse.cdt.core.parser.IParserCallback; import org.eclipse.cdt.core.parser.IParserCallback;
import org.eclipse.cdt.core.parser.IProblemReporter;
import org.eclipse.cdt.core.parser.IScanner; import org.eclipse.cdt.core.parser.IScanner;
import org.eclipse.cdt.core.parser.ITranslationResult;
import org.eclipse.cdt.core.parser.ISourceElementRequestor; import org.eclipse.cdt.core.parser.ISourceElementRequestor;
import org.eclipse.cdt.core.parser.IToken; import org.eclipse.cdt.core.parser.IToken;
import org.eclipse.cdt.core.parser.ParserFactory; import org.eclipse.cdt.core.parser.ParserFactory;
@ -34,6 +36,8 @@ import org.eclipse.cdt.core.parser.ast.IASTUsingDeclaration;
import org.eclipse.cdt.core.parser.ast.IASTUsingDirective; import org.eclipse.cdt.core.parser.ast.IASTUsingDirective;
import org.eclipse.cdt.core.parser.ast.IASTClassSpecifier.ClassNameType; import org.eclipse.cdt.core.parser.ast.IASTClassSpecifier.ClassNameType;
import org.eclipse.cdt.internal.core.model.Util; import org.eclipse.cdt.internal.core.model.Util;
/** /**
* This is our first implementation of the IParser interface, serving as a parser for * This is our first implementation of the IParser interface, serving as a parser for
* ANSI C and C++. * ANSI C and C++.
@ -58,6 +62,9 @@ public class Parser implements IParser
private ISourceElementRequestor requestor = null; private ISourceElementRequestor requestor = null;
// new callback mechanism // new callback mechanism
private IASTFactory astFactory = null; // ast factory private IASTFactory astFactory = null; // ast factory
private IProblemReporter problemReporter = null;
private ITranslationResult unitResult = null;
/** /**
* This is the single entry point for setting parsePassed to * This is the single entry point for setting parsePassed to
* false, and also making note what token offset we failed upon. * false, and also making note what token offset we failed upon.
@ -78,10 +85,12 @@ public class Parser implements IParser
* @param c IParserCallback instance that will receive callbacks as we parse * @param c IParserCallback instance that will receive callbacks as we parse
* @param quick Are we asking for a high level parse or not? * @param quick Are we asking for a high level parse or not?
*/ */
public Parser(IScanner s, IParserCallback c, ParserMode m) public Parser(IScanner s, IParserCallback c, ParserMode m, IProblemReporter problemReporter, ITranslationResult unitResult)
{ {
callback = c; callback = c;
scanner = s; scanner = s;
this.problemReporter = problemReporter;
this.unitResult = unitResult;
if (c instanceof ISourceElementRequestor) if (c instanceof ISourceElementRequestor)
setRequestor((ISourceElementRequestor)c); setRequestor((ISourceElementRequestor)c);
mode = m; mode = m;
@ -90,8 +99,11 @@ public class Parser implements IParser
scanner.setCallback(c); scanner.setCallback(c);
scanner.setASTFactory(astFactory); scanner.setASTFactory(astFactory);
} }
private static int parseCount = 0;
// counter that keeps track of the number of times Parser.parse() is called // counter that keeps track of the number of times Parser.parse() is called
private static int parseCount = 0;
/* (non-Javadoc) /* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.parser.IParser#parse() * @see org.eclipse.cdt.internal.core.parser.IParser#parse()
*/ */
@ -99,6 +111,7 @@ public class Parser implements IParser
{ {
long startTime = System.currentTimeMillis(); long startTime = System.currentTimeMillis();
translationUnit(); translationUnit();
onParseEnd();
// For the debuglog to take place, you have to call // For the debuglog to take place, you have to call
// Util.setDebugging(true); // Util.setDebugging(true);
// Or set debug to true in the core plugin preference // Or set debug to true in the core plugin preference
@ -111,6 +124,11 @@ public class Parser implements IParser
+ (parsePassed ? "" : " - parse failure")); + (parsePassed ? "" : " - parse failure"));
return parsePassed; return parsePassed;
} }
public void onParseEnd() {
scanner.onParseEnd();
}
/** /**
* This is the top-level entry point into the ANSI C++ grammar. * This is the top-level entry point into the ANSI C++ grammar.
* *

View file

@ -15,8 +15,11 @@ import java.util.Map;
import org.eclipse.cdt.core.parser.EndOfFile; import org.eclipse.cdt.core.parser.EndOfFile;
import org.eclipse.cdt.core.parser.IPreprocessor; import org.eclipse.cdt.core.parser.IPreprocessor;
import org.eclipse.cdt.core.parser.IProblemReporter;
import org.eclipse.cdt.core.parser.ITranslationResult;
import org.eclipse.cdt.core.parser.ScannerException; import org.eclipse.cdt.core.parser.ScannerException;
/** /**
* @author jcamelon * @author jcamelon
* *
@ -28,8 +31,8 @@ public class Preprocessor extends Scanner implements IPreprocessor {
* @param filename * @param filename
* @param defns * @param defns
*/ */
public Preprocessor(Reader reader, String filename, Map defns) { public Preprocessor(Reader reader, String filename, Map defns, IProblemReporter problemReporter, ITranslationResult unitResult) {
super(reader, filename, defns); super(reader, filename, defns, problemReporter, unitResult);
} }
public void process() public void process()

View file

@ -29,10 +29,13 @@ import org.eclipse.cdt.core.parser.EndOfFile;
import org.eclipse.cdt.core.parser.IMacroDescriptor; import org.eclipse.cdt.core.parser.IMacroDescriptor;
import org.eclipse.cdt.core.parser.IParser; import org.eclipse.cdt.core.parser.IParser;
import org.eclipse.cdt.core.parser.IParserCallback; import org.eclipse.cdt.core.parser.IParserCallback;
import org.eclipse.cdt.core.parser.IProblemReporter;
import org.eclipse.cdt.core.parser.IScanner; import org.eclipse.cdt.core.parser.IScanner;
import org.eclipse.cdt.core.parser.IScannerContext; import org.eclipse.cdt.core.parser.IScannerContext;
import org.eclipse.cdt.core.parser.ISourceElementRequestor; import org.eclipse.cdt.core.parser.ISourceElementRequestor;
import org.eclipse.cdt.core.parser.IToken; import org.eclipse.cdt.core.parser.IToken;
import org.eclipse.cdt.core.parser.ITranslationResult;
import org.eclipse.cdt.core.parser.ITranslationOptions;
import org.eclipse.cdt.core.parser.ParserFactory; import org.eclipse.cdt.core.parser.ParserFactory;
import org.eclipse.cdt.core.parser.ParserMode; import org.eclipse.cdt.core.parser.ParserMode;
import org.eclipse.cdt.core.parser.ScannerException; import org.eclipse.cdt.core.parser.ScannerException;
@ -48,7 +51,7 @@ import org.eclipse.cdt.core.parser.ast.IASTMacro;
public class Scanner implements IScanner { public class Scanner implements IScanner {
public Scanner(Reader reader, String filename, Map defns) { public Scanner(Reader reader, String filename, Map defns, IProblemReporter problemReporter, ITranslationResult unitResult) {
try { try {
//this is a hack to get around a sudden EOF experience //this is a hack to get around a sudden EOF experience
contextStack.push( contextStack.push(
@ -66,6 +69,14 @@ public class Scanner implements IScanner {
} }
if( defns != null ) if( defns != null )
definitions.putAll( defns ); definitions.putAll( defns );
this.problemReporter = problemReporter;
this.translationResult = unitResult;
if (problemReporter != null && problemReporter.getOptions() != null) {
this.taskTagsInfo = new TaskTagsInfo(problemReporter.getOptions());
}
} }
@ -154,7 +165,7 @@ public class Scanner implements IScanner {
int next = getChar(); int next = getChar();
if (next == '/') { if (next == '/') {
// single line comment // single line comment
skipOverTextUntilNewline(); skipOverSinglelineComment();
break; break;
} else if (next == '*') { } else if (next == '*') {
// multiline comment // multiline comment
@ -497,7 +508,7 @@ public class Scanner implements IScanner {
c = getChar(); c = getChar();
if( c == '/' ) if( c == '/' )
{ {
while (c != '\n' && c != NOCHAR) skipOverSinglelineComment();
c = getChar(); c = getChar();
continue; continue;
} }
@ -1316,8 +1327,7 @@ public class Scanner implements IScanner {
c = getChar(); c = getChar();
switch (c) { switch (c) {
case '/' : case '/' :
c = getChar(); skipOverSinglelineComment();
while (c != '\n' && c != NOCHAR)
c = getChar(); c = getChar();
continue; continue;
case '*' : case '*' :
@ -1442,8 +1452,7 @@ public class Scanner implements IScanner {
c = getChar(); c = getChar();
switch (c) { switch (c) {
case '/' : case '/' :
c = getChar(); skipOverSinglelineComment();
while (c != '\n' && c != NOCHAR)
c = getChar(); c = getChar();
continue; continue;
case '*' : case '*' :
@ -1651,8 +1660,9 @@ public class Scanner implements IScanner {
new StringReader(expression + ";"), new StringReader(expression + ";"),
EXPRESSION, EXPRESSION,
definitions, definitions,
null, ParserMode.COMPLETE_PARSE ); null, ParserMode.COMPLETE_PARSE,
IParser parser = ParserFactory.createParser(trial, evaluator, ParserMode.COMPLETE_PARSE ); problemReporter, translationResult );
IParser parser = ParserFactory.createParser(trial, evaluator, ParserMode.COMPLETE_PARSE, problemReporter, translationResult );
parser.expression(null); parser.expression(null);
expressionEvalResult = evaluator.getResult(); expressionEvalResult = evaluator.getResult();
@ -1689,15 +1699,42 @@ public class Scanner implements IScanner {
} }
} }
protected void skipOverSinglelineComment() throws ScannerException {
StringBuffer comment = new StringBuffer("//");
int commentOffset = lastContext.getOffset() - lastContext.undoStackSize() - 2;
int commentStartLine = lastContext.getLine();
int c;
loop:
for (;;) {
c = getChar();
comment.append((char)c);
switch (c) {
case NOCHAR :
case '\n' :
break loop;
default :
break;
}
}
checkTaskTag(comment, commentOffset, commentStartLine);
}
protected boolean skipOverMultilineComment() throws ScannerException { protected boolean skipOverMultilineComment() throws ScannerException {
int state = 0; int state = 0;
boolean encounteredNewline = false; boolean encounteredNewline = false;
StringBuffer comment = new StringBuffer("/*");
int commentOffset = lastContext.getOffset() - lastContext.undoStackSize() - 2;
int commentStartLine = lastContext.getLine();
// simple state machine to handle multi-line comments // simple state machine to handle multi-line comments
// state 0 == no end of comment in site // state 0 == no end of comment in site
// state 1 == encountered *, expecting / // state 1 == encountered *, expecting /
// state 2 == we are no longer in a comment // state 2 == we are no longer in a comment
int c = getChar(); int c = getChar();
comment.append((char)c);
while (state != 2 && c != NOCHAR) { while (state != 2 && c != NOCHAR) {
if (c == '\n') if (c == '\n')
encounteredNewline = true; encounteredNewline = true;
@ -1715,6 +1752,7 @@ public class Scanner implements IScanner {
break; break;
} }
c = getChar(); c = getChar();
comment.append((char)c);
} }
if (c == NOCHAR) { if (c == NOCHAR) {
@ -1724,6 +1762,8 @@ public class Scanner implements IScanner {
ungetChar(c); ungetChar(c);
checkTaskTag(comment, commentOffset, commentStartLine);
return encounteredNewline; return encounteredNewline;
} }
@ -1871,7 +1911,7 @@ public class Scanner implements IScanner {
if( ! replacementString.equals( "" ) ) if( ! replacementString.equals( "" ) )
{ {
IScanner helperScanner = ParserFactory.createScanner( new StringReader(replacementString), null, null, null, mode ); IScanner helperScanner = ParserFactory.createScanner( new StringReader(replacementString), null, null, null, mode, problemReporter, translationResult );
helperScanner.setTokenizingMacroReplacementList( true ); helperScanner.setTokenizingMacroReplacementList( true );
IToken t = helperScanner.nextToken(false); IToken t = helperScanner.nextToken(false);
@ -1928,7 +1968,7 @@ public class Scanner implements IScanner {
c = getChar(); c = getChar();
if (c == '/') // one line comment if (c == '/') // one line comment
{ {
skipOverTextUntilNewline(); skipOverSinglelineComment();
addDefinition(key, ""); addDefinition(key, "");
} else if (c == '*') // multi-line comment } else if (c == '*') // multi-line comment
{ {
@ -1969,7 +2009,7 @@ public class Scanner implements IScanner {
protected Vector getMacroParameters (String params, boolean forStringizing) throws ScannerException { protected Vector getMacroParameters (String params, boolean forStringizing) throws ScannerException {
IScanner tokenizer = ParserFactory.createScanner(new StringReader(params), TEXT, definitions, null, mode ); IScanner tokenizer = ParserFactory.createScanner(new StringReader(params), TEXT, definitions, null, mode, problemReporter, translationResult );
Vector parameterValues = new Vector(); Vector parameterValues = new Vector();
Token t = null; Token t = null;
String str = new String(); String str = new String();
@ -2206,4 +2246,170 @@ public class Scanner implements IScanner {
public void setASTFactory(IASTFactory f) { public void setASTFactory(IASTFactory f) {
astFactory = f; astFactory = f;
} }
// task tag support
private class TaskTagsInfo {
char[][] taskTags = null;
char[][] taskPriorities = null;
class FoundTaskInfo {
char[] foundTaskTags = null;
char[] foundTaskMessages = null;
char[] foundTaskPriorities = null;
int foundTaskStartOffset = -1;
int foundTaskEndOffset = -1;
int foundTaskLine = -1;
};
FoundTaskInfo[] foundTaskInfo = null;
int foundTaskCount = 0;
TaskTagsInfo(ITranslationOptions options) {
this.taskTags = options.getTaskTags();
this.taskPriorities = options.getTaskPriorities();
}
}
IProblemReporter problemReporter = null;
ITranslationResult translationResult = null;
TaskTagsInfo taskTagsInfo = null;
// check presence of task tags
public void checkTaskTag(StringBuffer comment, int commentStart, int commentStartLine) {
if (this.taskTagsInfo == null) return;
int commentLength = comment.length();
int tagStartLine = commentStartLine;
int foundTaskIndex = taskTagsInfo.foundTaskCount;
char[][] taskTags = taskTagsInfo.taskTags;
char[][] taskPriorities = taskTagsInfo.taskPriorities;
// only look for newer task tags
if (foundTaskIndex > 0) {
TaskTagsInfo.FoundTaskInfo lastInfo = taskTagsInfo.foundTaskInfo[foundTaskIndex-1];
if (lastInfo.foundTaskStartOffset >= commentStart)
return;
}
nextChar:
for (int i = 0; i < commentLength; i++) {
if (comment.charAt(i) == '\n') tagStartLine++;
int nextPos = -1;
char[] tag = null;
char[] priority = null;
int tagLength = 0;
// check for tag occurrence
nextTag:
for (int itag = 0; itag < taskTags.length; itag++) {
tag = taskTags[itag];
tagLength = tag.length;
priority = (taskPriorities != null && itag < taskPriorities.length)
? taskPriorities[itag]
: null;
for (int t = 0; t < tagLength; t++){
if (comment.charAt(i+t) != tag[t]) continue nextTag;
}
nextPos = i + tagLength;
int fTC = taskTagsInfo.foundTaskCount;
if (taskTagsInfo.foundTaskInfo == null) {
taskTagsInfo.foundTaskInfo = new TaskTagsInfo.FoundTaskInfo[5];
} else if (fTC == taskTagsInfo.foundTaskInfo.length) {
TaskTagsInfo.FoundTaskInfo[] resizedFTI = new TaskTagsInfo.FoundTaskInfo[fTC*2];
System.arraycopy(taskTagsInfo.foundTaskInfo, 0, resizedFTI, 0, fTC);
}
TaskTagsInfo.FoundTaskInfo lastFTI = taskTagsInfo.new FoundTaskInfo();
lastFTI.foundTaskTags = tag;
lastFTI.foundTaskPriorities = priority;
lastFTI.foundTaskStartOffset = i;
lastFTI.foundTaskLine = tagStartLine;
taskTagsInfo.foundTaskInfo[fTC] = lastFTI;
taskTagsInfo.foundTaskCount++;
for (int jj=i+1; jj<nextPos; jj++) {
if (comment.charAt(jj) == '\n') {
tagStartLine++;
}
}
i = nextPos;
}
}
for (int i = foundTaskIndex; i < taskTagsInfo.foundTaskCount; i++) {
// retrieve message start and end positions
TaskTagsInfo.FoundTaskInfo fTI = taskTagsInfo.foundTaskInfo[i];
TaskTagsInfo.FoundTaskInfo fTI2 = taskTagsInfo.foundTaskInfo[i+1];
int msgStart = fTI.foundTaskStartOffset + fTI.foundTaskTags.length;
int end;
char c;
int max_value = (i + 1 < taskTagsInfo.foundTaskCount)
? fTI2.foundTaskStartOffset - 1
: Integer.MAX_VALUE;
end = -1;
for (int j = msgStart; j < commentLength; j++){
if ((c = comment.charAt(j)) == '\n' || c == '\r'){
end = j - 1;
break;
}
}
end = end < max_value ? end : max_value;
if (end < 0){
for (int j = commentLength-1; j >= msgStart; j--){
if ((c = comment.charAt(j)) == '*') {
end = j-1;
break;
}
}
if (end < 0) end = commentLength-1;
}
// trim the message
while (Character.isWhitespace(comment.charAt(end)) && msgStart <= end) end--;
while (Character.isWhitespace(comment.charAt(msgStart)) && msgStart <= end) msgStart++;
// update the end position of the task
fTI.foundTaskEndOffset = end;
// get the message source
final int messageLength = end-msgStart+1;
char[] message = new char[messageLength];
comment.getChars(msgStart, msgStart + messageLength, message, 0);
fTI.foundTaskMessages = message;
fTI.foundTaskStartOffset += commentStart;
fTI.foundTaskEndOffset += commentStart;
}
}
public void onParseEnd() {
if (problemReporter != null && taskTagsInfo != null){
for (int i = 0; i < taskTagsInfo.foundTaskCount; i++) {
TaskTagsInfo.FoundTaskInfo fTI = taskTagsInfo.foundTaskInfo[i];
problemReporter.task(
new String(fTI.foundTaskTags),
new String(fTI.foundTaskMessages),
fTI.foundTaskPriorities == null ? null : new String(fTI.foundTaskPriorities),
fTI.foundTaskStartOffset,
fTI.foundTaskEndOffset,
fTI.foundTaskLine,
this.translationResult);
}
}
}
} }

View file

@ -23,6 +23,7 @@ public class ScannerContext implements IScannerContext
private String filename; private String filename;
private int macroOffset = -1; private int macroOffset = -1;
private int macroLength = -1; private int macroLength = -1;
private int line = 1;
private int offset; private int offset;
private Stack undo = new Stack(); private Stack undo = new Stack();
private int kind; private int kind;
@ -30,9 +31,9 @@ public class ScannerContext implements IScannerContext
public ScannerContext(){} public ScannerContext(){}
/* (non-Javadoc) /* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.parser.IScannerContext#initialize(Reader, String, int, IASTInclusion, int, int) * @see org.eclipse.cdt.internal.core.parser.IScannerContext#initialize(Reader, String, int, IASTInclusion, int, int, int)
*/ */
public IScannerContext initialize(Reader r, String f, int k, IASTInclusion i, int mO, int mL) public IScannerContext initialize(Reader r, String f, int k, IASTInclusion i, int mO, int mL, int l)
{ {
reader = r; reader = r;
filename = f; filename = f;
@ -41,6 +42,7 @@ public class ScannerContext implements IScannerContext
inc = i; inc = i;
macroOffset = mO; macroOffset = mO;
macroLength = mL; macroLength = mL;
line = l;
return this; return this;
} }
@ -49,12 +51,14 @@ public class ScannerContext implements IScannerContext
*/ */
public IScannerContext initialize(Reader r, String f, int k, IASTInclusion i) public IScannerContext initialize(Reader r, String f, int k, IASTInclusion i)
{ {
return initialize(r, f, k, i, -1, -1); return initialize(r, f, k, i, -1, -1, 1);
} }
public int read() throws IOException { public int read() throws IOException {
++offset; ++offset;
return reader.read(); int c = reader.read();
if ((char)c == '\n') line++;
return c;
} }
/** /**
@ -100,6 +104,14 @@ public class ScannerContext implements IScannerContext
return offset; return offset;
} }
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.parser.IScannerContext#getLine()
*/
public final int getLine()
{
return line;
}
/** /**
* Returns the reader. * Returns the reader.
* @return Reader * @return Reader
@ -120,7 +132,9 @@ public class ScannerContext implements IScannerContext
*/ */
public final int popUndo() public final int popUndo()
{ {
return ((Integer)undo.pop()).intValue(); int c = ((Integer)undo.pop()).intValue();
if ((char)c == '\n') line++;
return c;
} }
/** /**
@ -129,6 +143,7 @@ public class ScannerContext implements IScannerContext
*/ */
public void pushUndo(int undo) public void pushUndo(int undo)
{ {
if ((char)undo == '\n') line--;
this.undo.push( new Integer( undo )); this.undo.push( new Integer( undo ));
} }

View file

@ -0,0 +1,136 @@
/*******************************************************************************
* Copyright (c) 2000, 2003 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Common Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/cpl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.internal.core.parser;
import java.util.Iterator;
import java.util.Map;
import java.util.StringTokenizer;
import org.eclipse.cdt.core.parser.ITranslationOptions;
public class TranslationOptions implements ITranslationOptions {
// tags used to recognize tasks in comments
private char[][] taskTags = null;
// priorities of tasks in comments
private char[][] taskPriorities = null;
public TranslationOptions(Map settings) {
initialize(settings);
}
/**
* Initializing the translation options with external settings
*/
public void initialize(Map settings){
if (settings == null) return;
// filter out related options
Iterator entries = settings.entrySet().iterator();
while (entries.hasNext()) {
Map.Entry entry = (Map.Entry)entries.next();
Object oKey = entry.getKey();
Object oValue = entry.getValue();
if (!(oKey instanceof String)) continue;
if (!(oValue instanceof String)) continue;
String optionID = (String) oKey;
String optionValue = (String) oValue;
// Unpack task tags
if (optionID.equals(OPTION_TaskTags)) {
if (optionValue.length() == 0) {
this.taskTags = null;
} else {
StringTokenizer tokenizer = new StringTokenizer(optionValue, ",");
this.taskTags = new char[tokenizer.countTokens()][];
int i = 0;
while (tokenizer.hasMoreTokens()) {
String token = tokenizer.nextToken().trim();
this.taskTags[i] = token.toCharArray();
i++;
}
}
continue;
}
// Unpack task priorities
if (optionID.equals(OPTION_TaskPriorities)){
if (optionValue.length() == 0) {
this.taskPriorities = null;
} else {
StringTokenizer tokenizer = new StringTokenizer(optionValue, ",");
this.taskPriorities = new char[tokenizer.countTokens()][];
int i = 0;
while (tokenizer.hasMoreTokens()) {
String token = tokenizer.nextToken().trim();
this.taskPriorities[i] = token.toCharArray();
i++;
}
}
continue;
}
}
}
public void setTaskTags(char[][] taskTags) {
this.taskTags = taskTags;
}
public char[][] getTaskTags() {
return taskTags;
}
public void setTaskPriorities(char[][] taskPriorities) {
this.taskPriorities = taskPriorities;
}
public char[][] getTaskPriorities() {
return taskPriorities;
}
public String toString() {
StringBuffer buf = new StringBuffer("TranslationOptions:"); //$NON-NLS-1$
String result = "";
if (this.taskTags != null) {
for (int i=0; i<this.taskTags.length; i++) {
result += this.taskTags.toString();
if (i<this.taskTags.length-1) result += ",";
}
}
buf.append("\n-task tags: " + result); //$NON-NLS-1$
result = "";
if (this.taskPriorities != null) {
for (int i=0; i<this.taskPriorities.length; i++) {
result += this.taskPriorities.toString();
if (i<this.taskPriorities.length-1) result += ",";
}
}
buf.append("\n-task priorities : " + result); //$NON-NLS-1$
return buf.toString();
}
}

View file

@ -0,0 +1,382 @@
/*******************************************************************************
* Copyright (c) 2000, 2003 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Common Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/cpl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.internal.core.parser;
/**
* A translation result consists of all information returned during translation for
* a translation unit. This includes:
* <ul>
* <li> the translation unit that was processed
* <li> any problems (errors, warnings, tasks etc.) produced
* </ul>
*/
import org.eclipse.cdt.core.parser.*;
import org.eclipse.cdt.core.parser.IProblem;
import org.eclipse.cdt.core.model.ITranslationUnit;
public class TranslationResult implements ITranslationResult {
public IProblem problems[];
public IProblem tasks[];
public int problemCount;
public int taskCount;
public ITranslationUnit translationUnit;
private int maxProblemPerUnit;
public int unitIndex, totalUnitsKnown;
public boolean hasBeenAccepted = false;
public char[] fileName;
public TranslationResult(
char[] fileName,
int unitIndex,
int totalUnitsKnown,
int maxProblemPerUnit){
this.fileName = fileName;
this.unitIndex = unitIndex;
this.totalUnitsKnown = totalUnitsKnown;
this.maxProblemPerUnit = maxProblemPerUnit;
}
public static final int DEFAULT_MAX_PROBLEMS_PER_UNIT = 100;
public TranslationResult(
ITranslationUnit translationUnit) {
this(translationUnit, 1, 1, DEFAULT_MAX_PROBLEMS_PER_UNIT);
}
public TranslationResult(
ITranslationUnit translationUnit,
int unitIndex,
int totalUnitsKnown,
int maxProblemPerUnit){
this.fileName = translationUnit.getPath().lastSegment().toCharArray();
this.translationUnit = translationUnit;
this.unitIndex = unitIndex;
this.totalUnitsKnown = totalUnitsKnown;
this.maxProblemPerUnit = maxProblemPerUnit;
}
private int computePriority(IProblem problem) {
// early problems first
int priority = 100000 - problem.getSourceLineNumber();
return priority;
}
public IProblem[] getAllProblems() {
IProblem[] problems = this.getProblems();
int problemCount = problems != null ? problems.length : 0;
IProblem[] tasks = this.getTasks();
int taskCount = tasks != null ? tasks.length : 0;
if (taskCount == 0) {
return problems;
}
if (problemCount == 0) {
return tasks;
}
int totalNumberOfProblem = problemCount + taskCount;
IProblem[] allProblems = new IProblem[totalNumberOfProblem];
int allProblemIndex = 0;
int taskIndex = 0;
int problemIndex = 0;
while (taskIndex + problemIndex < totalNumberOfProblem) {
IProblem nextTask = null;
IProblem nextProblem = null;
if (taskIndex < taskCount) {
nextTask = tasks[taskIndex];
}
if (problemIndex < problemCount) {
nextProblem = problems[problemIndex];
}
// select the next problem
IProblem currentProblem = null;
if (nextProblem != null) {
if (nextTask != null) {
if (nextProblem.getSourceStart() < nextTask.getSourceStart()) {
currentProblem = nextProblem;
problemIndex++;
} else {
currentProblem = nextTask;
taskIndex++;
}
} else {
currentProblem = nextProblem;
problemIndex++;
}
} else {
if (nextTask != null) {
currentProblem = nextTask;
taskIndex++;
}
}
allProblems[allProblemIndex++] = currentProblem;
}
return allProblems;
}
/**
* Answer the initial translation unit corresponding to the present translation result
*/
public ITranslationUnit getTranslationUnit() {
return translationUnit;
}
/**
* Answer the initial file name
*/
public char[] getFileName() {
return fileName;
}
/**
* Answer the errors encountered during translation.
*/
public IProblem[] getErrors() {
IProblem[] problems = getProblems();
int errorCount = 0;
for (int i = 0; i < this.problemCount; i++) {
if (problems[i].isError()) errorCount++;
}
if (errorCount == this.problemCount) return problems;
IProblem[] errors = new IProblem[errorCount];
int index = 0;
for (int i = 0; i < this.problemCount; i++) {
if (problems[i].isError()) errors[index++] = problems[i];
}
return errors;
}
/**
* Answer the problems (errors and warnings) encountered during translation.
*
* This is not a compiler internal API - it has side-effects !
* It is intended to be used only once all problems have been detected,
* and makes sure the problems slot as the exact size of the number of
* problems.
*/
public IProblem[] getProblems() {
// Re-adjust the size of the problems if necessary.
if (problems != null) {
if (this.problemCount != problems.length) {
System.arraycopy(problems, 0, (problems = new IProblem[problemCount]), 0, problemCount);
}
if (this.maxProblemPerUnit > 0 && this.problemCount > this.maxProblemPerUnit){
quickPrioritize(problems, 0, problemCount - 1);
this.problemCount = this.maxProblemPerUnit;
System.arraycopy(problems, 0, (problems = new IProblem[problemCount]), 0, problemCount);
}
// Sort problems per source positions.
quickSort(problems, 0, problems.length-1);
}
return problems;
}
/**
* Answer the tasks (TO-DO, ...) encountered during translation.
*
* This is not a compiler internal API - it has side-effects !
* It is intended to be used only once all problems have been detected,
* and makes sure the problems slot as the exact size of the number of
* problems.
*/
public IProblem[] getTasks() {
// Re-adjust the size of the tasks if necessary.
if (this.tasks != null) {
if (this.taskCount != this.tasks.length) {
System.arraycopy(this.tasks, 0, (this.tasks = new IProblem[this.taskCount]), 0, this.taskCount);
}
quickSort(tasks, 0, tasks.length-1);
}
return this.tasks;
}
public boolean hasErrors() {
if (problems != null)
for (int i = 0; i < problemCount; i++) {
if (problems[i].isError())
return true;
}
return false;
}
public boolean hasProblems() {
return problemCount != 0;
}
public boolean hasSyntaxError(){
if (problems != null)
for (int i = 0; i < problemCount; i++) {
IProblem problem = problems[i];
if ((problem.getID() & IProblem.Syntax) != 0 && problem.isError())
return true;
}
return false;
}
public boolean hasTasks() {
return this.taskCount != 0;
}
public boolean hasWarnings() {
if (problems != null)
for (int i = 0; i < problemCount; i++) {
if (problems[i].isWarning())
return true;
}
return false;
}
private static void quickSort(IProblem[] list, int left, int right) {
if (left >= right) return;
// sort the problems by their source start position... starting with 0
int original_left = left;
int original_right = right;
int mid = list[(left + right) / 2].getSourceStart();
do {
while (list[left].getSourceStart() < mid)
left++;
while (mid < list[right].getSourceStart())
right--;
if (left <= right) {
IProblem tmp = list[left];
list[left] = list[right];
list[right] = tmp;
left++;
right--;
}
} while (left <= right);
if (original_left < right)
quickSort(list, original_left, right);
if (left < original_right)
quickSort(list, left, original_right);
}
private void quickPrioritize(IProblem[] list, int left, int right) {
if (left >= right) return;
// sort the problems by their priority... starting with the highest priority
int original_left = left;
int original_right = right;
int mid = computePriority(list[(left + right) / 2]);
do {
while (computePriority(list[right]) < mid)
right--;
while (mid < computePriority(list[left]))
left++;
if (left <= right) {
IProblem tmp = list[left];
list[left] = list[right];
list[right] = tmp;
left++;
right--;
}
} while (left <= right);
if (original_left < right)
quickPrioritize(list, original_left, right);
if (left < original_right)
quickPrioritize(list, left, original_right);
}
public void record(IProblem newProblem, IReferenceContext referenceContext) {
if (newProblem.getID() == IProblem.Task) {
recordTask(newProblem);
return;
}
if (problemCount == 0) {
problems = new IProblem[5];
} else if (problemCount == problems.length) {
System.arraycopy(problems, 0, (problems = new IProblem[problemCount * 2]), 0, problemCount);
}
problems[problemCount++] = newProblem;
}
private void recordTask(IProblem newProblem) {
if (this.taskCount == 0) {
this.tasks = new IProblem[5];
} else if (this.taskCount == this.tasks.length) {
System.arraycopy(this.tasks, 0, (this.tasks = new IProblem[this.taskCount * 2]), 0, this.taskCount);
}
this.tasks[this.taskCount++] = newProblem;
}
public ITranslationResult tagAsAccepted() {
this.hasBeenAccepted = true;
return this;
}
public String toString() {
StringBuffer buffer = new StringBuffer();
if (this.fileName != null){
buffer.append("Filename : ").append(this.fileName).append('\n'); //$NON-NLS-1$
}
if (problems != null){
buffer.append(this.problemCount).append(" PROBLEM(s) detected \n"); //$NON-NLS-1$//$NON-NLS-2$
for (int i = 0; i < this.problemCount; i++){
buffer.append("\t - ").append(this.problems[i]).append('\n'); //$NON-NLS-1$
}
} else {
buffer.append("No PROBLEM\n"); //$NON-NLS-1$
}
return buffer.toString();
}
}

View file

@ -0,0 +1,249 @@
/*******************************************************************************
* Copyright (c) 2000, 2003 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Common Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/cpl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.internal.core.parser.problem;
import org.eclipse.cdt.core.model.ITranslationUnit;
import org.eclipse.cdt.core.parser.IProblem;
public class DefaultProblem implements IProblem {
private char[] fileName;
private int id;
private int startPosition, endPosition, line;
private int severity;
private String[] arguments;
private String message;
public DefaultProblem(
char[] originatingFileName,
String message,
int id,
String[] stringArguments,
int severity,
int startPosition,
int endPosition,
int line) {
this.fileName = originatingFileName;
this.message = message;
this.id = id;
this.arguments = stringArguments;
this.severity = severity;
this.startPosition = startPosition;
this.endPosition = endPosition;
this.line = line;
}
public String errorReportSource(ITranslationUnit translationUnit) {
//extra from the source the innacurate token
//and "highlight" it using some underneath ^^^^^
//put some context around too.
//this code assumes that the font used in the console is fixed size
//sanity .....
if ((startPosition > endPosition)
|| ((startPosition <= 0) && (endPosition <= 0)))
return "\n!! no source information available !!";
final char SPACE = '\u0020';
final char MARK = '^';
final char TAB = '\t';
char[] source = translationUnit.getContents();
//the next code tries to underline the token.....
//it assumes (for a good display) that token source does not
//contain any \r \n. This is false on statements !
//(the code still works but the display is not optimal !)
//compute the how-much-char we are displaying around the inaccurate token
int begin = startPosition >= source.length ? source.length - 1 : startPosition;
int relativeStart = 0;
int end = endPosition >= source.length ? source.length - 1 : endPosition;
int relativeEnd = 0;
label : for (relativeStart = 0;; relativeStart++) {
if (begin == 0)
break label;
if ((source[begin - 1] == '\n') || (source[begin - 1] == '\r'))
break label;
begin--;
}
label : for (relativeEnd = 0;; relativeEnd++) {
if ((end + 1) >= source.length)
break label;
if ((source[end + 1] == '\r') || (source[end + 1] == '\n')) {
break label;
}
end++;
}
//extract the message form the source
char[] extract = new char[end - begin + 1];
System.arraycopy(source, begin, extract, 0, extract.length);
char c;
//remove all SPACE and TAB that begin the error message...
int trimLeftIndex = 0;
while (((c = extract[trimLeftIndex++]) == TAB) || (c == SPACE)) {
};
System.arraycopy(
extract,
trimLeftIndex - 1,
extract = new char[extract.length - trimLeftIndex + 1],
0,
extract.length);
relativeStart -= trimLeftIndex;
//buffer spaces and tabs in order to reach the error position
int pos = 0;
char[] underneath = new char[extract.length]; // can't be bigger
for (int i = 0; i <= relativeStart; i++) {
if (extract[i] == TAB) {
underneath[pos++] = TAB;
} else {
underneath[pos++] = SPACE;
}
}
//mark the error position
for (int i = startPosition;
i <= (endPosition >= source.length ? source.length - 1 : endPosition);
i++)
underneath[pos++] = MARK;
//resize underneathto remove 'null' chars
System.arraycopy(underneath, 0, underneath = new char[pos], 0, pos);
return " at line" + String.valueOf(line)
+ "\n\t" + new String(extract) + "\n\t" + new String(underneath); //$NON-NLS-2$ //$NON-NLS-1$
}
/**
* Answer back the original arguments recorded into the problem.
* @return java.lang.String[]
*/
public String[] getArguments() {
return arguments;
}
/**
* Answer the type of problem.
* @see org.eclipse.cdt.core.parser.IProblem#getID()
* @return int
*/
public int getID() {
return id;
}
/**
* Answer a localized, human-readable message string which describes the problem.
* @return java.lang.String
*/
public String getMessage() {
return message;
}
/**
* Answer the file name in which the problem was found.
* @return char[]
*/
public char[] getOriginatingFileName() {
return fileName;
}
/**
* Answer the end position of the problem (inclusive), or -1 if unknown.
* @return int
*/
public int getSourceEnd() {
return endPosition;
}
/**
* Answer the line number in source where the problem begins.
* @return int
*/
public int getSourceLineNumber() {
return line;
}
/**
* Answer the start position of the problem (inclusive), or -1 if unknown.
* @return int
*/
public int getSourceStart() {
return startPosition;
}
/*
* Helper method: checks the severity to see if the Error bit is set.
* @return boolean
*/
public boolean isError() {
return (severity & IProblemSeverities.Error) != 0;
}
/*
* Helper method: checks the severity to see if the Warning bit is set.
* @return boolean
*/
public boolean isWarning() {
return (severity & IProblemSeverities.Warning) == 0;
}
/**
* Set the end position of the problem (inclusive), or -1 if unknown.
*
* Used for shifting problem positions.
* @param sourceEnd the new value of the sourceEnd of the receiver
*/
public void setSourceEnd(int sourceEnd) {
endPosition = sourceEnd;
}
/**
* Set the line number in source where the problem begins.
* @param lineNumber the new value of the line number of the receiver
*/
public void setSourceLineNumber(int lineNumber) {
line = lineNumber;
}
/**
* Set the start position of the problem (inclusive), or -1 if unknown.
*
* Used for shifting problem positions.
* @param sourceStart the new value of the source start position of the receiver
*/
public void setSourceStart(int sourceStart) {
startPosition = sourceStart;
}
public String toString() {
String s = "Pb(" + (id & IgnoreCategoriesMask) + ") "; //$NON-NLS-1$ //$NON-NLS-2$
if (message != null) {
s += message;
} else {
if (arguments != null)
for (int i = 0; i < arguments.length; i++)
s += " " + arguments[i]; //$NON-NLS-1$
}
return s;
}
}

View file

@ -0,0 +1,169 @@
/*******************************************************************************
* Copyright (c) 2000, 2003 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Common Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/cpl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.internal.core.parser.problem;
import java.util.Locale;
import java.util.MissingResourceException;
import java.util.ResourceBundle;
import org.eclipse.cdt.core.parser.IProblem;
import org.eclipse.cdt.internal.core.parser.IProblemFactory;
public class DefaultProblemFactory implements IProblemFactory {
public String[] messageTemplates;
private Locale locale;
private static String[] DEFAULT_LOCALE_TEMPLATES;
private final static char[] DOUBLE_QUOTES = "''".toCharArray(); //$NON-NLS-1$
private final static char[] SINGLE_QUOTE = "'".toCharArray(); //$NON-NLS-1$
/**
* @param loc the locale used to get the right message
*/
public DefaultProblemFactory(Locale loc) {
this.locale = loc;
if (Locale.getDefault().equals(loc)){
if (DEFAULT_LOCALE_TEMPLATES == null){
DEFAULT_LOCALE_TEMPLATES = loadMessageTemplates(loc);
}
this.messageTemplates = DEFAULT_LOCALE_TEMPLATES;
} else {
this.messageTemplates = loadMessageTemplates(loc);
}
}
/**
* Answer a new IProblem created according to the parameters value
* <ul>
* <li>originatingFileName the name of the file name from which the problem is originated
* <li>problemId the problem id
* <li>problemArguments the fully qualified arguments recorded inside the problem
* <li>messageArguments the arguments needed to set the error message (shorter names than problemArguments ones)
* <li>severity the severity of the problem
* <li>startPosition the starting position of the problem
* <li>endPosition the end position of the problem
* <li>lineNumber the line on which the problem occured
* </ul>
* @param originatingFileName char[]
* @param problemId int
* @param arguments String[]
* @param severity int
* @param startPosition int
* @param endPosition int
* @param lineNumber int
* @return org.eclipse.cdt.core.parser.IProblem
*/
public IProblem createProblem(
char[] originatingFileName,
int problemId,
String[] problemArguments,
String[] messageArguments,
int severity,
int startPosition,
int endPosition,
int lineNumber) {
return new DefaultProblem(
originatingFileName,
this.getLocalizedMessage(problemId, messageArguments),
problemId,
problemArguments,
severity,
startPosition,
endPosition,
lineNumber);
}
/**
* Answer the locale used to retrieve the error messages
* @return java.util.Locale
*/
public Locale getLocale() {
return locale;
}
public final String getLocalizedMessage(int id, String[] problemArguments) {
StringBuffer output = new StringBuffer(80);
String message =
messageTemplates[(id & IProblem.IgnoreCategoriesMask)];
if (message == null) {
return "Unable to retrieve the error message for problem id: " //$NON-NLS-1$
+ (id & IProblem.IgnoreCategoriesMask)
+ ". Check translation resources."; //$NON-NLS-1$
}
// for compatibility with MessageFormat which eliminates double quotes in original message
message = message.replace('\"', '\'');
int length = message.length();
int start = -1, end = length;
while (true) {
if ((end = message.indexOf('{', start)) > -1) {
output.append(message.substring(start + 1, end));
if ((start = message.indexOf('}', end)) > -1) {
try {
output.append(
problemArguments[Integer.parseInt(message.substring(end + 1, start))]);
} catch (NumberFormatException nfe) {
output.append(message.substring(end + 1, start + 1));
} catch (ArrayIndexOutOfBoundsException e) {
return "Corrupted translation resources for problem id: " //$NON-NLS-1$
+ (id & IProblem.IgnoreCategoriesMask)
+ ". Check translation resources."; //$NON-NLS-1$
}
} else {
output.append(message.substring(end, length));
break;
}
} else {
output.append(message.substring(start + 1, length));
break;
}
}
return output.toString();
}
/**
* @param problem org.eclipse.cdt.core.parser.IProblem
* @return String
*/
public final String localizedMessage(IProblem problem) {
return getLocalizedMessage(problem.getID(), problem.getArguments());
}
/**
* This method initializes the MessageTemplates class variable according
* to the current Locale.
*/
public static String[] loadMessageTemplates(Locale loc) {
ResourceBundle bundle = null;
String bundleName = "org.eclipse.cdt.internal.core.parser.problem.messages"; //$NON-NLS-1$
try {
bundle = ResourceBundle.getBundle(bundleName, loc);
} catch(MissingResourceException e) {
System.out.println("Missing resource : " + bundleName.replace('.', '/') + ".properties for locale " + loc); //$NON-NLS-1$//$NON-NLS-2$
throw e;
}
String[] templates = new String[500];
for (int i = 0, max = templates.length; i < max; i++) {
try {
templates[i] = bundle.getString(String.valueOf(i));
} catch (MissingResourceException e) {
// available ID
}
}
return templates;
}
public DefaultProblemFactory() {
this(Locale.getDefault());
}
}

View file

@ -0,0 +1,21 @@
/*******************************************************************************
* Copyright (c) 2000, 2003 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Common Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/cpl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.internal.core.parser.problem;
public interface IProblemSeverities {
final int Ignore = -1;
final int Error = 0x00001;
final int Warning = 0x00002;
final int Task = 0x10000; // when bit is set: the problem is a task
}

View file

@ -0,0 +1,157 @@
/*******************************************************************************
* Copyright (c) 2000, 2003 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Common Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/cpl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.internal.core.parser.problem;
import org.eclipse.cdt.core.parser.IProblem;
import org.eclipse.cdt.core.parser.IReferenceContext;
import org.eclipse.cdt.core.parser.ITranslationOptions;
import org.eclipse.cdt.core.parser.ITranslationResult;
import org.eclipse.cdt.internal.core.parser.IErrorHandlingPolicy;
import org.eclipse.cdt.internal.core.parser.IProblemFactory;
/*
* Translation problem handler, responsible to determine whether
* a problem is actually a warning or an error (or a task); also will
* decide whether the translation task can be processed further or not.
*
* Behavior : will request its current policy if need to stop on
* first error, and if should proceed (persist) with problems.
*/
public class ProblemHandler {
public final static String[] NoArgument = new String[0];
final public IErrorHandlingPolicy policy;
public final IProblemFactory problemFactory;
private final ITranslationOptions options;
/**
* Problem handler can be supplied with a policy to specify
* its behavior in error handling. Also see static methods for
* built-in policies.
*
*/
public ProblemHandler(IErrorHandlingPolicy policy, ITranslationOptions options, IProblemFactory problemFactory) {
this.policy = policy;
this.problemFactory = problemFactory;
this.options = options;
}
/**
* Given the current configuration, answers which category the problem
* falls into:
* Error | Warning | Ignore | Task
*/
public int computeSeverity(int problemId) {
if (problemId == IProblem.Task) return IProblemSeverities.Task;
// by default all problems are errors
return IProblemSeverities.Error;
}
public IProblem createProblem(
char[] fileName,
int problemId,
String[] problemArguments,
String[] messageArguments,
int severity,
int problemStartPosition,
int problemEndPosition,
int lineNumber,
IReferenceContext referenceContext,
ITranslationResult unitResult) {
return problemFactory.createProblem(
fileName,
problemId,
problemArguments,
messageArguments,
severity,
problemStartPosition,
problemEndPosition,
lineNumber);
}
public void handle(
int problemId,
String[] problemArguments,
String[] messageArguments,
int severity,
int problemStartPosition,
int problemEndPosition,
int line,
IReferenceContext referenceContext,
ITranslationResult unitResult) {
if (severity == IProblemSeverities.Ignore)
return;
IProblem problem =
this.createProblem(
unitResult.getFileName(),
problemId,
problemArguments,
messageArguments,
severity,
problemStartPosition,
problemEndPosition,
line >= 0
? line
: 1,
referenceContext,
unitResult);
if (problem == null) return; // problem couldn't be created, ignore
this.record(problem, unitResult, referenceContext);
}
/**
* Standard problem handling API, the actual severity (warning/error/ignore) is deducted
* from the problem ID and the current translation options.
*/
public void handle(
int problemId,
String[] problemArguments,
String[] messageArguments,
int problemStartPosition,
int problemEndPosition,
int line,
IReferenceContext referenceContext,
ITranslationResult unitResult) {
this.handle(
problemId,
problemArguments,
messageArguments,
this.computeSeverity(problemId), // severity inferred using the ID
problemStartPosition,
problemEndPosition,
line,
referenceContext,
unitResult);
}
public void record(IProblem problem, ITranslationResult unitResult, IReferenceContext referenceContext) {
unitResult.record(problem, referenceContext);
}
public ITranslationOptions getOptions() {
return options;
}
}

View file

@ -0,0 +1,110 @@
/*******************************************************************************
* Copyright (c) 2000, 2003 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Common Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/cpl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.internal.core.parser.problem;
import org.eclipse.cdt.core.parser.IProblem;
import org.eclipse.cdt.core.parser.IProblemReporter;
import org.eclipse.cdt.core.parser.IReferenceContext;
import org.eclipse.cdt.core.parser.ITranslationOptions;
import org.eclipse.cdt.core.parser.ITranslationResult;
import org.eclipse.cdt.internal.core.parser.IErrorHandlingPolicy;
import org.eclipse.cdt.internal.core.parser.IProblemFactory;
public class ProblemReporter extends ProblemHandler implements IProblemReporter {
public IReferenceContext referenceContext = null;
public ProblemReporter(IErrorHandlingPolicy policy, ITranslationOptions options, IProblemFactory problemFactory) {
super(policy, options, problemFactory);
}
public void task(String tag, String message, String priority, int start, int end, int line, ITranslationResult result){
this.handle(
IProblem.Task,
new String[] { tag, message, priority/*secret argument that is not surfaced in getMessage()*/},
new String[] { tag, message, priority/*secret argument that is not surfaced in getMessage()*/},
start,
end,
line,
result);
}
// use this private API when the translation unit result can be found through the
// reference context. Otherwise, use the other API taking a problem and a translation result
// as arguments
private void handle(
int problemId,
String[] problemArguments,
String[] messageArguments,
int problemStartPosition,
int problemEndPosition,
int line){
this.handle(
problemId,
problemArguments,
messageArguments,
problemStartPosition,
problemEndPosition,
line,
referenceContext,
referenceContext == null ? null : referenceContext.translationResult());
referenceContext = null;
}
// use this private API when the translation unit result can be found through the
// reference context. Otherwise, use the other API taking a problem and a translation result
// as arguments
private void handle(
int problemId,
String[] problemArguments,
String[] messageArguments,
int severity,
int problemStartPosition,
int problemEndPosition,
int line){
this.handle(
problemId,
problemArguments,
messageArguments,
severity,
problemStartPosition,
problemEndPosition,
referenceContext,
referenceContext == null ? null : referenceContext.translationResult());
referenceContext = null;
}
// use this private API when the translation unit result cannot be found through the
// reference context.
private void handle(
int problemId,
String[] problemArguments,
String[] messageArguments,
int problemStartPosition,
int problemEndPosition,
int line,
ITranslationResult unitResult){
this.handle(
problemId,
problemArguments,
messageArguments,
problemStartPosition,
problemEndPosition,
line,
referenceContext,
unitResult);
referenceContext = null;
}
}

View file

@ -0,0 +1,14 @@
###############################################################################
# Copyright (c) 2000, 2003 IBM Corporation and others.
# All rights reserved. This program and the accompanying materials
# are made available under the terms of the Common Public License v1.0
# which accompanies this distribution, and is available at
# http://www.eclipse.org/legal/cpl-v10.html
#
# Contributors:
# IBM Corporation - initial API and implementation
###############################################################################
0 = {0}
# Task message: {taskTag} {taskMessage}
450 = {0} {1}

View file

@ -18,3 +18,5 @@ makebuildmodel.name=Make Builder
ManagedBuildNature.name=Managed C/C++ Build Nature ManagedBuildNature.name=Managed C/C++ Build Nature
GeneratedMakefileCBuilder.name=Generated Makefile C/C++ Builder GeneratedMakefileCBuilder.name=Generated Makefile C/C++ Builder
CTaskName=C/C++ Task

View file

@ -280,4 +280,9 @@
</ignore> </ignore>
</extension> </extension>
<extension id="task" name="%CTaskName" point="org.eclipse.core.resources.markers">
<super type="org.eclipse.core.resources.taskmarker"/>
<persistent value="true"/>
</extension>
</plugin> </plugin>

View file

@ -8,12 +8,16 @@ package org.eclipse.cdt.core;
import java.text.MessageFormat; import java.text.MessageFormat;
import java.util.MissingResourceException; import java.util.MissingResourceException;
import java.util.ResourceBundle; import java.util.ResourceBundle;
import java.util.HashSet;
import java.util.HashMap;
import java.util.Iterator;
import org.eclipse.cdt.core.index.IndexModel; import org.eclipse.cdt.core.index.IndexModel;
import org.eclipse.cdt.core.model.CoreModel; import org.eclipse.cdt.core.model.CoreModel;
import org.eclipse.cdt.core.resources.IConsole; import org.eclipse.cdt.core.resources.IConsole;
import org.eclipse.cdt.internal.core.CDescriptorManager; import org.eclipse.cdt.internal.core.CDescriptorManager;
import org.eclipse.cdt.internal.core.CPathEntry; import org.eclipse.cdt.internal.core.CPathEntry;
import org.eclipse.cdt.internal.core.model.CModelManager;
import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IProjectDescription; import org.eclipse.core.resources.IProjectDescription;
import org.eclipse.core.resources.IWorkspace; import org.eclipse.core.resources.IWorkspace;
@ -29,6 +33,7 @@ import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.NullProgressMonitor; import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.OperationCanceledException; import org.eclipse.core.runtime.OperationCanceledException;
import org.eclipse.core.runtime.Plugin; import org.eclipse.core.runtime.Plugin;
import org.eclipse.core.runtime.Preferences;
import org.eclipse.core.runtime.Status; import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.SubProgressMonitor; import org.eclipse.core.runtime.SubProgressMonitor;
@ -48,6 +53,47 @@ public class CCorePlugin extends Plugin {
public final static String DEFAULT_BINARY_PARSER_UNIQ_ID = PLUGIN_ID + "." + DEFAULT_BINARY_PARSER_SIMPLE_ID; public final static String DEFAULT_BINARY_PARSER_UNIQ_ID = PLUGIN_ID + "." + DEFAULT_BINARY_PARSER_SIMPLE_ID;
public final static String PREF_USE_NEW_PARSER = "useNewParser"; public final static String PREF_USE_NEW_PARSER = "useNewParser";
/**
* Possible configurable option ID.
* @see #getDefaultOptions
*/
public static final String TRANSLATION_TASK_PRIORITIES = PLUGIN_ID + ".translation.taskPriorities"; //$NON-NLS-1$
/**
* Possible configurable option value for TRANSLATION_TASK_PRIORITIES.
* @see #getDefaultOptions
*/
public static final String TRANSLATION_TASK_PRIORITY_HIGH = "HIGH"; //$NON-NLS-1$
/**
* Possible configurable option value for TRANSLATION_TASK_PRIORITIES.
* @see #getDefaultOptions
*/
public static final String TRANSLATION_TASK_PRIORITY_LOW = "LOW"; //$NON-NLS-1$
/**
* Possible configurable option value for TRANSLATION_TASK_PRIORITIES.
* @see #getDefaultOptions
*/
public static final String TRANSLATION_TASK_PRIORITY_NORMAL = "NORMAL"; //$NON-NLS-1$
/**
* Possible configurable option ID.
* @see #getDefaultOptions
*/
public static final String TRANSLATION_TASK_TAGS = PLUGIN_ID + ".translation.taskTags"; //$NON-NLS-1$
/**
* Default task tag
*/
public static final String DEFAULT_TASK_TAG = "TODO"; //$NON-NLS-1$
/**
* Default task priority
*/
public static final String DEFAULT_TASK_PRIORITY = TRANSLATION_TASK_PRIORITY_NORMAL;
/**
* Possible configurable option ID.
* @see #getDefaultOptions
*/
public static final String CORE_ENCODING = PLUGIN_ID + ".encoding"; //$NON-NLS-1$
private static CCorePlugin fgCPlugin; private static CCorePlugin fgCPlugin;
private static ResourceBundle fgResourceBundle; private static ResourceBundle fgResourceBundle;
@ -150,6 +196,202 @@ public class CCorePlugin extends Plugin {
getPluginPreferences().setDefault(PREF_USE_NEW_PARSER, true); getPluginPreferences().setDefault(PREF_USE_NEW_PARSER, true);
} }
/**
* TODO: Add all options here
* Returns a table of all known configurable options with their default values.
* These options allow to configure the behaviour of the underlying components.
* The client may safely use the result as a template that they can modify and
* then pass to <code>setOptions</code>.
*
* Helper constants have been defined on CCorePlugin for each of the option ID and
* their possible constant values.
*
* Note: more options might be added in further releases.
* <pre>
* RECOGNIZED OPTIONS:
* TRANSLATION / Define the Automatic Task Tags
* When the tag list is not empty, translation will issue a task marker whenever it encounters
* one of the corresponding tags inside any comment in C/C++ source code.
* Generated task messages will include the tag, and range until the next line separator or comment ending.
* Note that tasks messages are trimmed. If a tag is starting with a letter or digit, then it cannot be leaded by
* another letter or digit to be recognized ("fooToDo" will not be recognized as a task for tag "ToDo", but "foo#ToDo"
* will be detected for either tag "ToDo" or "#ToDo"). Respectively, a tag ending with a letter or digit cannot be followed
* by a letter or digit to be recognized ("ToDofoo" will not be recognized as a task for tag "ToDo", but "ToDo:foo" will
* be detected either for tag "ToDo" or "ToDo:").
* - option id: "org.eclipse.cdt.core.translation.taskTags"
* - possible values: { "<tag>[,<tag>]*" } where <tag> is a String without any wild-card or leading/trailing spaces
* - default: ""
*
* TRANSLATION / Define the Automatic Task Priorities
* In parallel with the Automatic Task Tags, this list defines the priorities (high, normal or low)
* of the task markers issued by the translation.
* If the default is specified, the priority of each task marker is "NORMAL".
* - option id: "org.eclipse.cdt.core.transltaion.taskPriorities"
* - possible values: { "<priority>[,<priority>]*" } where <priority> is one of "HIGH", "NORMAL" or "LOW"
* - default: ""
*
* CORE / Specify Default Source Encoding Format
* Get the encoding format for translated sources. This setting is read-only, it is equivalent
* to 'ResourcesPlugin.getEncoding()'.
* - option id: "org.eclipse.cdt.core.encoding"
* - possible values: { any of the supported encoding names}.
* - default: <platform default>
* </pre>
*
* @return a mutable map containing the default settings of all known options
* (key type: <code>String</code>; value type: <code>String</code>)
* @see #setOptions
*/
public static HashMap getDefaultOptions()
{
HashMap defaultOptions = new HashMap(10);
// see #initializeDefaultPluginPreferences() for changing default settings
Preferences preferences = getDefault().getPluginPreferences();
HashSet optionNames = CModelManager.OptionNames;
// get preferences set to their default
String[] defaultPropertyNames = preferences.defaultPropertyNames();
for (int i = 0; i < defaultPropertyNames.length; i++){
String propertyName = defaultPropertyNames[i];
if (optionNames.contains(propertyName)) {
defaultOptions.put(propertyName, preferences.getDefaultString(propertyName));
}
}
// get preferences not set to their default
String[] propertyNames = preferences.propertyNames();
for (int i = 0; i < propertyNames.length; i++){
String propertyName = propertyNames[i];
if (optionNames.contains(propertyName)) {
defaultOptions.put(propertyName, preferences.getDefaultString(propertyName));
}
}
// get encoding through resource plugin
defaultOptions.put(CORE_ENCODING, ResourcesPlugin.getEncoding());
return defaultOptions;
}
/**
* Initializes the default preferences settings for this plug-in.
* TODO: Add all options here
*/
protected void initializeDefaultPluginPreferences()
{
Preferences preferences = getPluginPreferences();
HashSet optionNames = CModelManager.OptionNames;
// Compiler settings
preferences.setDefault(TRANSLATION_TASK_TAGS, DEFAULT_TASK_TAG);
optionNames.add(TRANSLATION_TASK_TAGS);
preferences.setDefault(TRANSLATION_TASK_PRIORITIES, DEFAULT_TASK_PRIORITY);
optionNames.add(TRANSLATION_TASK_PRIORITIES);
}
/**
* Helper method for returning one option value only. Equivalent to <code>(String)CCorePlugin.getOptions().get(optionName)</code>
* Note that it may answer <code>null</code> if this option does not exist.
* <p>
* For a complete description of the configurable options, see <code>getDefaultOptions</code>.
* </p>
*
* @param optionName the name of an option
* @return the String value of a given option
* @see CCorePlugin#getDefaultOptions
*/
public static String getOption(String optionName) {
if (CORE_ENCODING.equals(optionName)){
return ResourcesPlugin.getEncoding();
}
if (CModelManager.OptionNames.contains(optionName)){
Preferences preferences = getDefault().getPluginPreferences();
return preferences.getString(optionName).trim();
}
return null;
}
/**
* Returns the table of the current options. Initially, all options have their default values,
* and this method returns a table that includes all known options.
* <p>
* For a complete description of the configurable options, see <code>getDefaultOptions</code>.
* </p>
*
* @return table of current settings of all options
* (key type: <code>String</code>; value type: <code>String</code>)
* @see CCorePlugin#getDefaultOptions
*/
public static HashMap getOptions() {
HashMap options = new HashMap(10);
// see #initializeDefaultPluginPreferences() for changing default settings
Plugin plugin = getDefault();
if (plugin != null) {
Preferences preferences = plugin.getPluginPreferences();
HashSet optionNames = CModelManager.OptionNames;
// get preferences set to their default
String[] defaultPropertyNames = preferences.defaultPropertyNames();
for (int i = 0; i < defaultPropertyNames.length; i++){
String propertyName = defaultPropertyNames[i];
if (optionNames.contains(propertyName)){
options.put(propertyName, preferences.getDefaultString(propertyName));
}
}
// get preferences not set to their default
String[] propertyNames = preferences.propertyNames();
for (int i = 0; i < propertyNames.length; i++){
String propertyName = propertyNames[i];
if (optionNames.contains(propertyName)){
options.put(propertyName, preferences.getString(propertyName).trim());
}
}
// get encoding through resource plugin
options.put(CORE_ENCODING, ResourcesPlugin.getEncoding());
}
return options;
}
/**
* Sets the current table of options. All and only the options explicitly included in the given table
* are remembered; all previous option settings are forgotten, including ones not explicitly
* mentioned.
* <p>
* For a complete description of the configurable options, see <code>getDefaultOptions</code>.
* </p>
*
* @param newOptions the new options (key type: <code>String</code>; value type: <code>String</code>),
* or <code>null</code> to reset all options to their default values
* @see CCorePlugin#getDefaultOptions
*/
public static void setOptions(HashMap newOptions) {
// see #initializeDefaultPluginPreferences() for changing default settings
Preferences preferences = getDefault().getPluginPreferences();
if (newOptions == null){
newOptions = getDefaultOptions();
}
Iterator keys = newOptions.keySet().iterator();
while (keys.hasNext()){
String key = (String)keys.next();
if (!CModelManager.OptionNames.contains(key)) continue; // unrecognized option
if (key.equals(CORE_ENCODING)) continue; // skipped, contributed by resource prefs
String value = (String)newOptions.get(key);
preferences.setValue(key, value);
}
// persist options
getDefault().savePluginPreferences();
}
public IConsole getConsole(String id) { public IConsole getConsole(String id) {
try { try {
IExtensionPoint extension = getDescriptor().getExtensionPoint("CBuildConsole"); IExtensionPoint extension = getDescriptor().getExtensionPoint("CBuildConsole");

View file

@ -7,6 +7,9 @@
* src/org/eclipse/cdt/internal/ui/preferences/CProjectPropertyPage.java * src/org/eclipse/cdt/internal/ui/preferences/CProjectPropertyPage.java
* src/org/eclipse/cdt/internal/ui/CPluginResources.properties * src/org/eclipse/cdt/internal/ui/CPluginResources.properties
2003-06-26 Victor Mozgin
Task tags support in C/C++ comments (initial revision).
2003-06-25 John Camelon 2003-06-25 John Camelon
Create new interface and support for calculating lineNumber/offset mapping. Create new interface and support for calculating lineNumber/offset mapping.
Updated IASTClassSpecifier for qualified name query. Updated IASTClassSpecifier for qualified name query.

View file

@ -75,6 +75,9 @@ CApplicationLauncher.label=Executable
CApplicationLauncher.description=Launch a local command CApplicationLauncher.description=Launch a local command
CProblemMarker.name=C Problem CProblemMarker.name=C Problem
todoPageName=C/C++ Task Tags
todoTaskPrefName=Task Tags
Editors.DefaultTextEditor = Default Text Editor Editors.DefaultTextEditor = Default Text Editor
AsmEditor.name = Assembly Editor AsmEditor.name = Assembly Editor

View file

@ -316,6 +316,12 @@
class="org.eclipse.cdt.internal.ui.preferences.BuildConsolePreferencePage" class="org.eclipse.cdt.internal.ui.preferences.BuildConsolePreferencePage"
id="org.eclipse.cdt.ui.preferneces.CBuildConsolePreferernces"> id="org.eclipse.cdt.ui.preferneces.CBuildConsolePreferernces">
</page> </page>
<page
name="%todoTaskPrefName"
id = "org.eclipse.cdt.ui.preferences.TodoTaskPreferencePage"
class="org.eclipse.cdt.internal.ui.preferences.TodoTaskPreferencePage"
category= "org.eclipse.cdt.ui.preferences.CPluginPreferencePage">
</page>
</extension> </extension>
<extension <extension
point="org.eclipse.ui.propertyPages"> point="org.eclipse.ui.propertyPages">
@ -340,6 +346,13 @@
value="org.eclipse.cdt.core.managedBuildNature"> value="org.eclipse.cdt.core.managedBuildNature">
</filter> </filter>
</page> </page>
<page
name="%todoPageName"
id="org.eclipse.cdt.ui.propertyPages.TodoTaskPropertyPage"
objectClass="org.eclipse.core.resources.IProject"
class="org.eclipse.cdt.internal.ui.preferences.TodoTaskPropertyPage">
<filter name="nature" value="org.eclipse.cdt.core.cnature"/>
</page>
</extension> </extension>
<extension <extension
point="org.eclipse.ui.editorActions"> point="org.eclipse.ui.editorActions">

View file

@ -38,6 +38,10 @@ public interface ICHelpContextIds {
public static final String PROJ_CONF_BLOCK= PREFIX + "new_proj_conf_block_context"; public static final String PROJ_CONF_BLOCK= PREFIX + "new_proj_conf_block_context";
public static final String TODO_TASK_INPUT_DIALOG= PREFIX + "todo_task_input_dialog_context"; //$NON-NLS-1$
public static final String TODO_TASK_PROPERTY_PAGE= PREFIX + "tasktags_property_page_context"; //$NON-NLS-1$
public static final String TODO_TASK_PREFERENCE_PAGE= PREFIX + "tasktags_preference_page_context"; //$NON-NLS-1$
// Console view // Console view
public static final String CLEAR_CONSOLE_ACTION= PREFIX + "clear_console_action_context"; public static final String CLEAR_CONSOLE_ACTION= PREFIX + "clear_console_action_context";
public static final String CLEAR_CONSOLE_VIEW= PREFIX + "clear_console_view_context"; public static final String CLEAR_CONSOLE_VIEW= PREFIX + "clear_console_view_context";

View file

@ -10,6 +10,7 @@ import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.StringTokenizer; import java.util.StringTokenizer;
import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.model.CModelException; import org.eclipse.cdt.core.model.CModelException;
import org.eclipse.cdt.core.model.CoreModel; import org.eclipse.cdt.core.model.CoreModel;
import org.eclipse.cdt.core.model.ICElement; import org.eclipse.cdt.core.model.ICElement;
@ -27,6 +28,7 @@ import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IMarker; import org.eclipse.core.resources.IMarker;
import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.Preferences;
import org.eclipse.jface.action.IAction; import org.eclipse.jface.action.IAction;
import org.eclipse.jface.action.IMenuManager; import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.IStatusLineManager; import org.eclipse.jface.action.IStatusLineManager;
@ -83,6 +85,8 @@ import org.eclipse.ui.texteditor.SourceViewerDecorationSupport;
import org.eclipse.ui.texteditor.TextOperationAction; import org.eclipse.ui.texteditor.TextOperationAction;
import org.eclipse.ui.views.contentoutline.IContentOutlinePage; import org.eclipse.ui.views.contentoutline.IContentOutlinePage;
import org.eclipse.ui.views.tasklist.TaskList; import org.eclipse.ui.views.tasklist.TaskList;
/** /**
* C specific text editor. * C specific text editor.
*/ */
@ -95,6 +99,9 @@ public class CEditor extends TextEditor implements ISelectionChangedListener {
protected ISelectionChangedListener fStatusLineClearer; protected ISelectionChangedListener fStatusLineClearer;
/** The property change listener */
private PropertyChangeListener fPropertyChangeListener = new PropertyChangeListener();
protected final static char[] BRACKETS = { '{', '}', '(', ')', '[', ']' }; protected final static char[] BRACKETS = { '{', '}', '(', ')', '[', ']' };
protected CPairMatcher fBracketMatcher = new CPairMatcher(BRACKETS); protected CPairMatcher fBracketMatcher = new CPairMatcher(BRACKETS);
@ -116,6 +123,21 @@ public class CEditor extends TextEditor implements ISelectionChangedListener {
/** Preference key for linked position color */ /** Preference key for linked position color */
public final static String LINKED_POSITION_COLOR = "linkedPositionColor"; //$NON-NLS-1$ public final static String LINKED_POSITION_COLOR = "linkedPositionColor"; //$NON-NLS-1$
/** Preference key for compiler task tags */
private final static String TRANSLATION_TASK_TAGS= CCorePlugin.TRANSLATION_TASK_TAGS;
private class PropertyChangeListener implements org.eclipse.core.runtime.Preferences.IPropertyChangeListener, org.eclipse.jface.util.IPropertyChangeListener {
/*
* @see IPropertyChangeListener#propertyChange(PropertyChangeEvent)
*/
public void propertyChange(org.eclipse.jface.util.PropertyChangeEvent event) {
handlePreferencePropertyChanged(event);
}
public void propertyChange(org.eclipse.core.runtime.Preferences.PropertyChangeEvent event) {
handlePreferencePropertyChanged(new org.eclipse.jface.util.PropertyChangeEvent(event.getSource(), event.getProperty(), event.getOldValue(), event.getNewValue()));
}
};
/** /**
* Default constructor. * Default constructor.
*/ */
@ -361,6 +383,12 @@ public class CEditor extends TextEditor implements ISelectionChangedListener {
fBracketMatcher.dispose(); fBracketMatcher.dispose();
fBracketMatcher = null; fBracketMatcher = null;
} }
if (fPropertyChangeListener != null) {
Preferences preferences = CCorePlugin.getDefault().getPluginPreferences();
preferences.removePropertyChangeListener(fPropertyChangeListener);
IPreferenceStore preferenceStore = getPreferenceStore();
preferenceStore.removePropertyChangeListener(fPropertyChangeListener);
}
super.dispose(); super.dispose();
} }
@ -460,6 +488,12 @@ public class CEditor extends TextEditor implements ISelectionChangedListener {
if (isTabConversionEnabled()) if (isTabConversionEnabled())
startTabConversion(); startTabConversion();
IPreferenceStore preferenceStore = getPreferenceStore();
preferenceStore.addPropertyChangeListener(fPropertyChangeListener);
Preferences preferences = CCorePlugin.getDefault().getPluginPreferences();
preferences.addPropertyChangeListener(fPropertyChangeListener);
} }
private IMarker getNextError(int offset, boolean forward) { private IMarker getNextError(int offset, boolean forward) {
@ -802,4 +836,18 @@ public class CEditor extends TextEditor implements ISelectionChangedListener {
setKeyBindingScopes(new String [] { "org.eclipse.cdt.ui.cEditorScope" } ); setKeyBindingScopes(new String [] { "org.eclipse.cdt.ui.cEditorScope" } );
} }
/**
* Handles a property change event describing a change
* of the C core's preferences and updates the preference
* related editor properties.
*
* @param event the property change event
*/
protected void handlePreferencePropertyChanged(org.eclipse.jface.util.PropertyChangeEvent event) {
if (TRANSLATION_TASK_TAGS.equals(event.getProperty())) {
ISourceViewer sourceViewer= getSourceViewer();
if (sourceViewer != null && affectsTextPresentation(event))
sourceViewer.invalidateTextPresentation();
}
}
} }

View file

@ -177,7 +177,9 @@ public class CMarkerAnnotation extends MarkerAnnotation implements IProblemAnnot
} else { } else {
if(marker.isSubtypeOf(ICModelMarker.C_MODEL_PROBLEM_MARKER)) { //|| getMarker().isSubtypeOf(IMarker.SEVERITY_WARNING)) { if(marker.isSubtypeOf(ICModelMarker.C_MODEL_PROBLEM_MARKER)) { //|| getMarker().isSubtypeOf(IMarker.SEVERITY_WARNING)) {
fIsProblemMarker= true; fIsProblemMarker= true;
} } else if (marker.isSubtypeOf(IMarker.TASK) || marker.isSubtypeOf(ICModelMarker.TASK_MARKER)) {
fIsProblemMarker= false;
} else
fIsProblemMarker = true; fIsProblemMarker = true;
} }

View file

@ -6,9 +6,11 @@ package org.eclipse.cdt.internal.ui.editor.asm;
*/ */
import org.eclipse.cdt.internal.ui.text.ICColorConstants; import org.eclipse.cdt.internal.ui.text.ICColorConstants;
import org.eclipse.cdt.internal.ui.text.CCommentScanner;
import org.eclipse.cdt.internal.ui.text.SingleTokenCScanner; import org.eclipse.cdt.internal.ui.text.SingleTokenCScanner;
import org.eclipse.cdt.internal.ui.text.util.CColorManager; import org.eclipse.cdt.internal.ui.text.util.CColorManager;
import org.eclipse.cdt.ui.CUIPlugin; import org.eclipse.cdt.ui.CUIPlugin;
import org.eclipse.core.runtime.Preferences;
import org.eclipse.jface.preference.IPreferenceStore; import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.text.IDocumentPartitioner; import org.eclipse.jface.text.IDocumentPartitioner;
import org.eclipse.jface.text.rules.DefaultPartitioner; import org.eclipse.jface.text.rules.DefaultPartitioner;
@ -24,11 +26,15 @@ import org.eclipse.jface.util.PropertyChangeEvent;
*/ */
public class AsmTextTools { public class AsmTextTools {
private class PreferenceListener implements IPropertyChangeListener { private class PreferenceListener implements IPropertyChangeListener, Preferences.IPropertyChangeListener {
public void propertyChange(PropertyChangeEvent event) { public void propertyChange(PropertyChangeEvent event) {
adaptToPreferenceChange(event); adaptToPreferenceChange(event);
} }
public void propertyChange(Preferences.PropertyChangeEvent event) {
adaptToPreferenceChange(new PropertyChangeEvent(event.getSource(), event.getProperty(), event.getOldValue(), event.getNewValue()));
}
}; };
/** The color manager -- use the same as for C code */ /** The color manager -- use the same as for C code */
private CColorManager fColorManager; private CColorManager fColorManager;
/** The Asm source code scanner */ /** The Asm source code scanner */
@ -36,15 +42,17 @@ public class AsmTextTools {
/** The Asm partitions scanner */ /** The Asm partitions scanner */
private AsmPartitionScanner fPartitionScanner; private AsmPartitionScanner fPartitionScanner;
/** The ASM multiline comment scanner */ /** The ASM multiline comment scanner */
private SingleTokenCScanner fMultilineCommentScanner; private CCommentScanner fMultilineCommentScanner;
/** The ASM singleline comment scanner */ /** The ASM singleline comment scanner */
private SingleTokenCScanner fSinglelineCommentScanner; private CCommentScanner fSinglelineCommentScanner;
/** The ASM string scanner */ /** The ASM string scanner */
private SingleTokenCScanner fStringScanner; private SingleTokenCScanner fStringScanner;
/** The preference store */ /** The preference store */
private IPreferenceStore fPreferenceStore; private IPreferenceStore fPreferenceStore;
/** The core preference store */
private Preferences fCorePreferenceStore;
/** The preference change listener */ /** The preference change listener */
private PreferenceListener fPreferenceListener= new PreferenceListener(); private PreferenceListener fPreferenceListener= new PreferenceListener();
@ -54,17 +62,32 @@ public class AsmTextTools {
* and initializes all members of this collection. * and initializes all members of this collection.
*/ */
public AsmTextTools(IPreferenceStore store) { public AsmTextTools(IPreferenceStore store) {
this(store, null);
}
/**
* Creates a new Asm text tools collection and eagerly creates
* and initializes all members of this collection.
*/
public AsmTextTools(IPreferenceStore store, Preferences coreStore) {
if(store == null) { if(store == null) {
store = CUIPlugin.getDefault().getPreferenceStore(); store = CUIPlugin.getDefault().getPreferenceStore();
} }
store.addPropertyChangeListener(fPreferenceListener);
fPreferenceStore = store; fPreferenceStore = store;
store.addPropertyChangeListener(fPreferenceListener);
fCorePreferenceStore= coreStore;
if (fCorePreferenceStore != null) {
fCorePreferenceStore.addPropertyChangeListener(fPreferenceListener);
}
fColorManager= new CColorManager(); fColorManager= new CColorManager();
fCodeScanner= new AsmCodeScanner(fColorManager, store); fCodeScanner= new AsmCodeScanner(fColorManager, store);
fPartitionScanner= new AsmPartitionScanner(); fPartitionScanner= new AsmPartitionScanner();
fMultilineCommentScanner= new SingleTokenCScanner(fColorManager, store, ICColorConstants.C_MULTI_LINE_COMMENT); fMultilineCommentScanner= new CCommentScanner(fColorManager, store, coreStore, ICColorConstants.C_MULTI_LINE_COMMENT);
fSinglelineCommentScanner= new SingleTokenCScanner(fColorManager, store, ICColorConstants.C_SINGLE_LINE_COMMENT); fSinglelineCommentScanner= new CCommentScanner(fColorManager, store, coreStore, ICColorConstants.C_SINGLE_LINE_COMMENT);
fStringScanner= new SingleTokenCScanner(fColorManager, store, ICColorConstants.C_STRING); fStringScanner= new SingleTokenCScanner(fColorManager, store, ICColorConstants.C_STRING);
} }
@ -95,6 +118,12 @@ public class AsmTextTools {
if (fPreferenceStore != null) { if (fPreferenceStore != null) {
fPreferenceStore.removePropertyChangeListener(fPreferenceListener); fPreferenceStore.removePropertyChangeListener(fPreferenceListener);
fPreferenceStore= null; fPreferenceStore= null;
if (fCorePreferenceStore != null) {
fCorePreferenceStore.removePropertyChangeListener(fPreferenceListener);
fCorePreferenceStore= null;
}
fPreferenceListener= null; fPreferenceListener= null;
} }
} }

View file

@ -22,6 +22,7 @@ import org.eclipse.cdt.internal.ui.text.CTextTools;
import org.eclipse.cdt.internal.ui.text.ContentAssistPreference; import org.eclipse.cdt.internal.ui.text.ContentAssistPreference;
import org.eclipse.cdt.internal.ui.text.ICColorConstants; import org.eclipse.cdt.internal.ui.text.ICColorConstants;
import org.eclipse.cdt.ui.CUIPlugin; import org.eclipse.cdt.ui.CUIPlugin;
import org.eclipse.cdt.ui.PreferenceConstants;
import org.eclipse.cdt.utils.ui.controls.TabFolderLayout; import org.eclipse.cdt.utils.ui.controls.TabFolderLayout;
import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.IStatus;
import org.eclipse.jface.preference.IPreferenceStore; import org.eclipse.jface.preference.IPreferenceStore;
@ -71,7 +72,8 @@ public class CEditorPreferencePage extends PreferencePage implements IWorkbenchP
"Keywords", ICColorConstants.C_KEYWORD }, { "Keywords", ICColorConstants.C_KEYWORD }, {
"Built-in types", ICColorConstants.C_TYPE }, { "Built-in types", ICColorConstants.C_TYPE }, {
"Strings", ICColorConstants.C_STRING }, { "Strings", ICColorConstants.C_STRING }, {
"Others", ICColorConstants.C_DEFAULT } "Others", ICColorConstants.C_DEFAULT }, {
PreferencesMessages.getString("CEditorPreferencePage.cCommentTaskTags"), PreferenceConstants.EDITOR_TASK_TAG_COLOR }
}; };
protected final String[][] fAppearanceColorListModel = new String[][] { { "Line number color", TextEditorPreferenceConstants.EDITOR_LINE_NUMBER_RULER_COLOR }, //$NON-NLS-1$ protected final String[][] fAppearanceColorListModel = new String[][] { { "Line number color", TextEditorPreferenceConstants.EDITOR_LINE_NUMBER_RULER_COLOR }, //$NON-NLS-1$
@ -246,6 +248,14 @@ public class CEditorPreferencePage extends PreferencePage implements IWorkbenchP
//new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.STRING, ContentAssistPreference.PARAMETERS_FOREGROUND), //new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.STRING, ContentAssistPreference.PARAMETERS_FOREGROUND),
//new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.STRING, ContentAssistPreference.AUTOACTIVATION_TRIGGERS_JAVADOC), //new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.STRING, ContentAssistPreference.AUTOACTIVATION_TRIGGERS_JAVADOC),
overlayKeys.add(new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.STRING, PreferenceConstants.EDITOR_TASK_TAG_COLOR));
overlayKeys.add(new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, PreferenceConstants.EDITOR_TASK_TAG_BOLD));
overlayKeys.add(new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.STRING, PreferenceConstants.EDITOR_TASK_INDICATION_COLOR));
overlayKeys.add(new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, PreferenceConstants.EDITOR_TASK_INDICATION));
overlayKeys.add(new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, PreferenceConstants.EDITOR_TASK_INDICATION_IN_OVERVIEW_RULER));
OverlayPreferenceStore.OverlayKey[] keys = new OverlayPreferenceStore.OverlayKey[overlayKeys.size()]; OverlayPreferenceStore.OverlayKey[] keys = new OverlayPreferenceStore.OverlayKey[overlayKeys.size()];
overlayKeys.toArray(keys); overlayKeys.toArray(keys);
return new OverlayPreferenceStore(getPreferenceStore(), keys); return new OverlayPreferenceStore(getPreferenceStore(), keys);

View file

@ -0,0 +1,400 @@
/*******************************************************************************
* Copyright (c) 2000, 2003 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Common Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/cpl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.internal.ui.preferences;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.StringTokenizer;
import org.eclipse.core.resources.IncrementalProjectBuilder;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.SubProgressMonitor;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;
import org.eclipse.swt.widgets.Widget;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.dialogs.ProgressMonitorDialog;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.cdt.core.model.ICProject;
import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.ui.CUIPlugin;
import org.eclipse.cdt.internal.ui.util.ExceptionHandler;
import org.eclipse.cdt.internal.ui.wizards.IStatusChangeListener;
/**
*/
public abstract class OptionsConfigurationBlock {
protected static class ControlData {
private String fKey;
private String[] fValues;
public ControlData(String key, String[] values) {
fKey= key;
fValues= values;
}
public String getKey() {
return fKey;
}
public String getValue(boolean selection) {
int index= selection ? 0 : 1;
return fValues[index];
}
public String getValue(int index) {
return fValues[index];
}
public int getSelection(String value) {
for (int i= 0; i < fValues.length; i++) {
if (value.equals(fValues[i])) {
return i;
}
}
throw new IllegalArgumentException();
}
}
protected Map fWorkingValues;
protected ArrayList fCheckBoxes;
protected ArrayList fComboBoxes;
protected ArrayList fTextBoxes;
private SelectionListener fSelectionListener;
private ModifyListener fTextModifyListener;
protected IStatusChangeListener fContext;
protected ICProject fProject; // project or null
private Shell fShell;
public OptionsConfigurationBlock(IStatusChangeListener context, ICProject project) {
fContext= context;
fProject= project;
fWorkingValues= getOptions(true);
fCheckBoxes= new ArrayList();
fComboBoxes= new ArrayList();
fTextBoxes= new ArrayList(2);
}
protected abstract String[] getAllKeys();
protected Map getOptions(boolean inheritCCoreOptions) {
if (fProject != null) {
return fProject.getOptions(inheritCCoreOptions);
} else {
return CCorePlugin.getOptions();
}
}
protected Map getDefaultOptions() {
return CCorePlugin.getDefaultOptions();
}
public final boolean hasProjectSpecificOptions() {
if (fProject != null) {
Map settings= fProject.getOptions(false);
String[] allKeys= getAllKeys();
for (int i= 0; i < allKeys.length; i++) {
if (settings.get(allKeys[i]) != null) {
return true;
}
}
}
return false;
}
protected final void setOptions(Map map) {
if (fProject != null) {
fProject.setOptions(map);
} else {
CCorePlugin.setOptions((HashMap) map);
}
}
protected Shell getShell() {
return fShell;
}
protected void setShell(Shell shell) {
fShell= shell;
}
protected abstract Control createContents(Composite parent);
protected void addCheckBox(Composite parent, String label, String key, String[] values, int indent) {
ControlData data= new ControlData(key, values);
GridData gd= new GridData(GridData.HORIZONTAL_ALIGN_FILL);
gd.horizontalSpan= 2;
gd.horizontalIndent= indent;
Button checkBox= new Button(parent, SWT.CHECK);
checkBox.setText(label);
checkBox.setData(data);
checkBox.setLayoutData(gd);
checkBox.addSelectionListener(getSelectionListener());
String currValue= (String)fWorkingValues.get(key);
checkBox.setSelection(data.getSelection(currValue) == 0);
fCheckBoxes.add(checkBox);
}
protected void addComboBox(Composite parent, String label, String key, String[] values, String[] valueLabels, int indent) {
ControlData data= new ControlData(key, values);
GridData gd= new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING);
gd.horizontalIndent= indent;
Label labelControl= new Label(parent, SWT.LEFT | SWT.WRAP);
labelControl.setText(label);
labelControl.setLayoutData(gd);
Combo comboBox= new Combo(parent, SWT.READ_ONLY);
comboBox.setItems(valueLabels);
comboBox.setData(data);
comboBox.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL));
comboBox.addSelectionListener(getSelectionListener());
String currValue= (String)fWorkingValues.get(key);
comboBox.select(data.getSelection(currValue));
fComboBoxes.add(comboBox);
}
protected Text addTextField(Composite parent, String label, String key, int indent, int widthHint) {
Label labelControl= new Label(parent, SWT.NONE);
labelControl.setText(label);
labelControl.setLayoutData(new GridData());
Text textBox= new Text(parent, SWT.BORDER | SWT.SINGLE);
textBox.setData(key);
textBox.setLayoutData(new GridData());
String currValue= (String) fWorkingValues.get(key);
textBox.setText(currValue);
textBox.addModifyListener(getTextModifyListener());
GridData data= new GridData(GridData.HORIZONTAL_ALIGN_FILL);
if (widthHint != 0) {
data.widthHint= widthHint;
}
data.horizontalIndent= indent;
textBox.setLayoutData(data);
fTextBoxes.add(textBox);
return textBox;
}
protected SelectionListener getSelectionListener() {
if (fSelectionListener == null) {
fSelectionListener= new SelectionListener() {
public void widgetDefaultSelected(SelectionEvent e) {}
public void widgetSelected(SelectionEvent e) {
controlChanged(e.widget);
}
};
}
return fSelectionListener;
}
protected ModifyListener getTextModifyListener() {
if (fTextModifyListener == null) {
fTextModifyListener= new ModifyListener() {
public void modifyText(ModifyEvent e) {
textChanged((Text) e.widget);
}
};
}
return fTextModifyListener;
}
protected void controlChanged(Widget widget) {
ControlData data= (ControlData) widget.getData();
String newValue= null;
if (widget instanceof Button) {
newValue= data.getValue(((Button)widget).getSelection());
} else if (widget instanceof Combo) {
newValue= data.getValue(((Combo)widget).getSelectionIndex());
} else {
return;
}
fWorkingValues.put(data.getKey(), newValue);
validateSettings(data.getKey(), newValue);
}
protected void textChanged(Text textControl) {
String key= (String) textControl.getData();
String number= textControl.getText();
fWorkingValues.put(key, number);
validateSettings(key, number);
}
protected boolean checkValue(String key, String value) {
return value.equals(fWorkingValues.get(key));
}
/* (non-javadoc)
* Update fields and validate.
* @param changedKey Key that changed, or null, if all changed.
*/
protected abstract void validateSettings(String changedKey, String newValue);
protected String[] getTokens(String text, String separator) {
StringTokenizer tok= new StringTokenizer(text, separator); //$NON-NLS-1$
int nTokens= tok.countTokens();
String[] res= new String[nTokens];
for (int i= 0; i < res.length; i++) {
res[i]= tok.nextToken().trim();
}
return res;
}
public boolean performOk(boolean enabled) {
String[] allKeys= getAllKeys();
Map actualOptions= getOptions(false);
// preserve other options
boolean hasChanges= false;
for (int i= 0; i < allKeys.length; i++) {
String key= allKeys[i];
String oldVal= (String) actualOptions.get(key);
String val= null;
if (enabled) {
val= (String) fWorkingValues.get(key);
if (!val.equals(oldVal)) {
hasChanges= true;
actualOptions.put(key, val);
}
} else {
if (oldVal != null) {
actualOptions.remove(key);
hasChanges= true;
}
}
}
if (hasChanges) {
boolean doBuild= false;
String[] strings= getFullBuildDialogStrings(fProject == null);
if (strings != null) {
MessageDialog dialog= new MessageDialog(getShell(), strings[0], null, strings[1], MessageDialog.QUESTION, new String[] { IDialogConstants.YES_LABEL, IDialogConstants.NO_LABEL, IDialogConstants.CANCEL_LABEL }, 2);
int res= dialog.open();
if (res == 0) {
doBuild= true;
} else if (res != 1) {
return false; // cancel pressed
}
}
setOptions(actualOptions);
if (doBuild) {
doFullBuild();
}
}
return true;
}
protected abstract String[] getFullBuildDialogStrings(boolean workspaceSettings);
protected void doFullBuild() {
ProgressMonitorDialog dialog= new ProgressMonitorDialog(getShell());
try {
dialog.run(true, true, new IRunnableWithProgress() {
public void run(IProgressMonitor monitor) throws InvocationTargetException {
monitor.beginTask("", 1); //$NON-NLS-1$
try {
if (fProject != null) {
monitor.setTaskName(PreferencesMessages.getFormattedString("OptionsConfigurationBlock.buildproject.taskname", fProject.getElementName())); //$NON-NLS-1$
fProject.getProject().build(IncrementalProjectBuilder.FULL_BUILD, new SubProgressMonitor(monitor,1));
} else {
monitor.setTaskName(PreferencesMessages.getString("OptionsConfigurationBlock.buildall.taskname")); //$NON-NLS-1$
CUIPlugin.getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, new SubProgressMonitor(monitor,1));
}
} catch (CoreException e) {
throw new InvocationTargetException(e);
} finally {
monitor.done();
}
}
});
} catch (InterruptedException e) {
// cancelled by user
} catch (InvocationTargetException e) {
String title= PreferencesMessages.getString("OptionsConfigurationBlock.builderror.title"); //$NON-NLS-1$
String message= PreferencesMessages.getString("OptionsConfigurationBlock.builderror.message"); //$NON-NLS-1$
ExceptionHandler.handle(e, getShell(), title, message);
}
}
public void performDefaults() {
fWorkingValues= getDefaultOptions();
updateControls();
validateSettings(null, null);
}
protected void updateControls() {
// update the UI
for (int i= fCheckBoxes.size() - 1; i >= 0; i--) {
Button curr= (Button) fCheckBoxes.get(i);
ControlData data= (ControlData) curr.getData();
String currValue= (String) fWorkingValues.get(data.getKey());
curr.setSelection(data.getSelection(currValue) == 0);
}
for (int i= fComboBoxes.size() - 1; i >= 0; i--) {
Combo curr= (Combo) fComboBoxes.get(i);
ControlData data= (ControlData) curr.getData();
String currValue= (String) fWorkingValues.get(data.getKey());
curr.select(data.getSelection(currValue));
}
for (int i= fTextBoxes.size() - 1; i >= 0; i--) {
Text curr= (Text) fTextBoxes.get(i);
String key= (String) curr.getData();
String currValue= (String) fWorkingValues.get(key);
curr.setText(currValue);
}
}
}

View file

@ -0,0 +1,41 @@
/*******************************************************************************
* Copyright (c) 2000, 2003 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Common Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/cpl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.internal.ui.preferences;
import java.text.MessageFormat;
import java.util.MissingResourceException;
import java.util.ResourceBundle;
public class PreferencesMessages {
private static final String RESOURCE_BUNDLE= "org.eclipse.cdt.internal.ui.preferences.PreferencesMessages";//$NON-NLS-1$
private static ResourceBundle fgResourceBundle= ResourceBundle.getBundle(RESOURCE_BUNDLE);
private PreferencesMessages() {
}
public static String getString(String key) {
try {
return fgResourceBundle.getString(key);
} catch (MissingResourceException e) {
return '!' + key + '!';
}
}
public static String getFormattedString(String key, String arg) {
return getFormattedString(key, new String[] { arg });
}
public static String getFormattedString(String key, String[] args) {
return MessageFormat.format(getString(key), args);
}
}

View file

@ -0,0 +1,51 @@
###############################################################################
# Copyright (c) 2000, 2003 IBM Corporation and others.
# All rights reserved. This program and the accompanying materials
# are made available under the terms of the Common Public License v1.0
# which accompanies this distribution, and is available at
# http://www.eclipse.org/legal/cpl-v10.html
#
# Contributors:
# IBM Corporation - initial API and implementation
###############################################################################
OptionsConfigurationBlock.builderror.title=Preference Changes
OptionsConfigurationBlock.builderror.message=Problem while building. Check log for details.
OptionsConfigurationBlock.buildall.taskname=Build all...
OptionsConfigurationBlock.buildproject.taskname=Build project ''{0}''...
TodoTaskPreferencePage.title=Task Tags
TodoTaskPropertyPage.useworkspacesettings.label=Use &workspace settings
TodoTaskPropertyPage.useworkspacesettings.change=&Configure Workspace Settings...
TodoTaskPropertyPage.useprojectsettings.label=Use pr&oject settings
TodoTaskConfigurationBlock.markers.tasks.high.priority=High
TodoTaskConfigurationBlock.markers.tasks.normal.priority=Normal
TodoTaskConfigurationBlock.markers.tasks.low.priority=Low
TodoTaskConfigurationBlock.markers.tasks.label=&Strings indicating tasks in Java comments:
TodoTaskConfigurationBlock.markers.tasks.add.button=Ne&w...
TodoTaskConfigurationBlock.markers.tasks.remove.button=Remo&ve
TodoTaskConfigurationBlock.markers.tasks.edit.button=Edi&t...
TodoTaskConfigurationBlock.markers.tasks.name.column=Tag
TodoTaskConfigurationBlock.markers.tasks.priority.column=Priority
TodoTaskConfigurationBlock.needsbuild.title=Task Tags Settings Changed
TodoTaskConfigurationBlock.needsfullbuild.message=The task tags settings have changed. A full rebuild is required to make changes effective. Do the full build now?
TodoTaskConfigurationBlock.needsprojectbuild.message=The task tags settings have changed. A rebuild of the project is required to make changes effective. Do the project build now?
TodoTaskInputDialog.new.title=New Task Tag
TodoTaskInputDialog.edit.title=Edit Task Tag
TodoTaskInputDialog.name.label=T&ag:
TodoTaskInputDialog.priority.label=&Priority:
TodoTaskInputDialog.priority.high=High
TodoTaskInputDialog.priority.normal=Normal
TodoTaskInputDialog.priority.low=Low
TodoTaskInputDialog.error.enterName=Enter task tag name.
TodoTaskInputDialog.error.comma=Name cannot contain a comma.
TodoTaskInputDialog.error.entryExists=Entry with the same name already exists.
TodoTaskInputDialog.error.noSpace=Name can not start or end with a whitespace.
CEditorPreferencePage.cCommentTaskTags=Task Tags

View file

@ -0,0 +1,294 @@
/*******************************************************************************
* Copyright (c) 2000, 2003 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Common Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/cpl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.internal.ui.preferences;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Table;
import org.eclipse.jface.viewers.ITableLabelProvider;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.model.ICProject;
import org.eclipse.cdt.internal.ui.dialogs.StatusInfo;
import org.eclipse.cdt.internal.ui.util.PixelConverter;
import org.eclipse.cdt.internal.ui.util.SWTUtil;
import org.eclipse.cdt.internal.ui.wizards.IStatusChangeListener;
import org.eclipse.cdt.internal.ui.wizards.dialogfields.DialogField;
import org.eclipse.cdt.internal.ui.wizards.dialogfields.IDialogFieldListener;
import org.eclipse.cdt.internal.ui.wizards.dialogfields.IListAdapter;
import org.eclipse.cdt.internal.ui.wizards.dialogfields.LayoutUtil;
import org.eclipse.cdt.internal.ui.wizards.dialogfields.ListDialogField;
/**
*/
public class TodoTaskConfigurationBlock extends OptionsConfigurationBlock {
private static final String PREF_TRANSLATION_TASK_TAGS= CCorePlugin.TRANSLATION_TASK_TAGS;
private static final String PREF_TRANSLATION_TASK_PRIORITIES= CCorePlugin.TRANSLATION_TASK_PRIORITIES;
private static final String PRIORITY_HIGH= CCorePlugin.TRANSLATION_TASK_PRIORITY_HIGH;
private static final String PRIORITY_NORMAL= CCorePlugin.TRANSLATION_TASK_PRIORITY_NORMAL;
private static final String PRIORITY_LOW= CCorePlugin.TRANSLATION_TASK_PRIORITY_LOW;
public static class TodoTask {
public String name;
public String priority;
}
private static class TodoTaskLabelProvider extends LabelProvider implements ITableLabelProvider {
/* (non-Javadoc)
* @see org.eclipse.jface.viewers.ILabelProvider#getImage(java.lang.Object)
*/
public Image getImage(Object element) {
return null;
}
/* (non-Javadoc)
* @see org.eclipse.jface.viewers.ILabelProvider#getText(java.lang.Object)
*/
public String getText(Object element) {
return getColumnText(element, 0);
}
/* (non-Javadoc)
* @see org.eclipse.jface.viewers.ITableLabelProvider#getColumnImage(java.lang.Object, int)
*/
public Image getColumnImage(Object element, int columnIndex) {
return null;
}
/* (non-Javadoc)
* @see org.eclipse.jface.viewers.ITableLabelProvider#getColumnText(java.lang.Object, int)
*/
public String getColumnText(Object element, int columnIndex) {
TodoTask task= (TodoTask) element;
if (columnIndex == 0) {
return task.name;
} else {
if (PRIORITY_HIGH.equals(task.priority)) {
return PreferencesMessages.getString("TodoTaskConfigurationBlock.markers.tasks.high.priority"); //$NON-NLS-1$
} else if (PRIORITY_NORMAL.equals(task.priority)) {
return PreferencesMessages.getString("TodoTaskConfigurationBlock.markers.tasks.normal.priority"); //$NON-NLS-1$
} else if (PRIORITY_LOW.equals(task.priority)) {
return PreferencesMessages.getString("TodoTaskConfigurationBlock.markers.tasks.low.priority"); //$NON-NLS-1$
}
return ""; //$NON-NLS-1$
}
}
}
private PixelConverter fPixelConverter;
private IStatus fTaskTagsStatus;
private ListDialogField fTodoTasksList;
public TodoTaskConfigurationBlock(IStatusChangeListener context, ICProject project) {
super(context, project);
TaskTagAdapter adapter= new TaskTagAdapter();
String[] buttons= new String[] {
/* 0 */ PreferencesMessages.getString("TodoTaskConfigurationBlock.markers.tasks.add.button"), //$NON-NLS-1$
/* 1 */ PreferencesMessages.getString("TodoTaskConfigurationBlock.markers.tasks.remove.button"), //$NON-NLS-1$
null,
/* 3 */ PreferencesMessages.getString("TodoTaskConfigurationBlock.markers.tasks.edit.button"), //$NON-NLS-1$
};
fTodoTasksList= new ListDialogField(adapter, buttons, new TodoTaskLabelProvider());
fTodoTasksList.setDialogFieldListener(adapter);
fTodoTasksList.setLabelText(PreferencesMessages.getString("TodoTaskConfigurationBlock.markers.tasks.label")); //$NON-NLS-1$
fTodoTasksList.setRemoveButtonIndex(1);
String[] columnsHeaders= new String[] {
PreferencesMessages.getString("TodoTaskConfigurationBlock.markers.tasks.name.column"), //$NON-NLS-1$
PreferencesMessages.getString("TodoTaskConfigurationBlock.markers.tasks.priority.column"), //$NON-NLS-1$
};
fTodoTasksList.setTableColumns(new ListDialogField.ColumnsDescription(columnsHeaders, true));
unpackTodoTasks();
if (fTodoTasksList.getSize() > 0) {
fTodoTasksList.selectFirstElement();
} else {
fTodoTasksList.enableButton(3, false);
}
fTaskTagsStatus= new StatusInfo();
}
protected final String[] getAllKeys() {
return new String[] {
PREF_TRANSLATION_TASK_TAGS, PREF_TRANSLATION_TASK_PRIORITIES
};
}
public class TaskTagAdapter implements IListAdapter, IDialogFieldListener {
private boolean canEdit(ListDialogField field) {
return field.getSelectedElements().size() == 1;
}
public void customButtonPressed(ListDialogField field, int index) {
doTodoButtonPressed(index);
}
public void selectionChanged(ListDialogField field) {
field.enableButton(3, canEdit(field));
}
public void doubleClicked(ListDialogField field) {
if (canEdit(field)) {
doTodoButtonPressed(3);
}
}
public void dialogFieldChanged(DialogField field) {
validateSettings(PREF_TRANSLATION_TASK_TAGS, null);
}
}
protected Control createContents(Composite parent) {
fPixelConverter= new PixelConverter(parent);
setShell(parent.getShell());
Composite markersComposite= createMarkersTabContent(parent);
validateSettings(null, null);
return markersComposite;
}
private Composite createMarkersTabContent(Composite folder) {
GridLayout layout= new GridLayout();
layout.marginHeight= 0;
layout.marginWidth= 0;
layout.numColumns= 2;
Composite markersComposite= new Composite(folder, SWT.NULL);
markersComposite.setLayout(layout);
fTodoTasksList.doFillIntoGrid(markersComposite, 3);
LayoutUtil.setHorizontalSpan(fTodoTasksList.getLabelControl(null), 2);
Table table= fTodoTasksList.getTableViewer().getTable();
GridData data= (GridData)fTodoTasksList.getListControl(null).getLayoutData();
data.grabExcessHorizontalSpace= true;
data.verticalAlignment= 0;
data.heightHint= SWTUtil.getTableHeightHint(table, 6);
return markersComposite;
}
protected void validateSettings(String changedKey, String newValue) {
if (changedKey != null) {
if (PREF_TRANSLATION_TASK_TAGS.equals(changedKey)) {
fTaskTagsStatus= validateTaskTags();
} else {
return;
}
} else {
fTaskTagsStatus= validateTaskTags();
}
IStatus status= fTaskTagsStatus; //StatusUtil.getMostSevere(new IStatus[] { fTaskTagsStatus });
fContext.statusChanged(status);
}
private IStatus validateTaskTags() {
return new StatusInfo();
}
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.ui.preferences.OptionsConfigurationBlock#performOk(boolean)
*/
public boolean performOk(boolean enabled) {
packTodoTasks();
return super.performOk(enabled);
}
protected String[] getFullBuildDialogStrings(boolean workspaceSettings) {
String title= PreferencesMessages.getString("TodoTaskConfigurationBlock.needsbuild.title"); //$NON-NLS-1$
String message;
if (fProject == null) {
message= PreferencesMessages.getString("TodoTaskConfigurationBlock.needsfullbuild.message"); //$NON-NLS-1$
} else {
message= PreferencesMessages.getString("TodoTaskConfigurationBlock.needsprojectbuild.message"); //$NON-NLS-1$
}
return new String[] { title, message };
}
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.ui.preferences.OptionsConfigurationBlock#updateControls()
*/
protected void updateControls() {
unpackTodoTasks();
}
private void unpackTodoTasks() {
String currTags= (String) fWorkingValues.get(PREF_TRANSLATION_TASK_TAGS);
String currPrios= (String) fWorkingValues.get(PREF_TRANSLATION_TASK_PRIORITIES);
String[] tags= getTokens(currTags, ","); //$NON-NLS-1$
String[] prios= getTokens(currPrios, ","); //$NON-NLS-1$
ArrayList elements= new ArrayList(tags.length);
for (int i= 0; i < tags.length; i++) {
TodoTask task= new TodoTask();
task.name= tags[i].trim();
task.priority= (i < prios.length) ? prios[i] : PRIORITY_NORMAL;
elements.add(task);
}
fTodoTasksList.setElements(elements);
}
private void packTodoTasks() {
StringBuffer tags= new StringBuffer();
StringBuffer prios= new StringBuffer();
List list= fTodoTasksList.getElements();
for (int i= 0; i < list.size(); i++) {
if (i > 0) {
tags.append(',');
prios.append(',');
}
TodoTask elem= (TodoTask) list.get(i);
tags.append(elem.name);
prios.append(elem.priority);
}
fWorkingValues.put(PREF_TRANSLATION_TASK_TAGS, tags.toString());
fWorkingValues.put(PREF_TRANSLATION_TASK_PRIORITIES, prios.toString());
}
private void doTodoButtonPressed(int index) {
TodoTask edited= null;
if (index != 0) {
edited= (TodoTask) fTodoTasksList.getSelectedElements().get(0);
}
TodoTaskInputDialog dialog= new TodoTaskInputDialog(getShell(), edited, fTodoTasksList.getElements());
if (dialog.open() == TodoTaskInputDialog.OK) {
if (edited != null) {
fTodoTasksList.replaceElement(edited, dialog.getResult());
} else {
fTodoTasksList.addElement(dialog.getResult());
}
}
}
}

View file

@ -0,0 +1,162 @@
/*******************************************************************************
* Copyright (c) 2000, 2003 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Common Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/cpl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.internal.ui.preferences;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.help.WorkbenchHelp;
import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.internal.ui.ICHelpContextIds;
import org.eclipse.cdt.internal.ui.dialogs.StatusDialog;
import org.eclipse.cdt.internal.ui.dialogs.StatusInfo;
import org.eclipse.cdt.internal.ui.preferences.TodoTaskConfigurationBlock.TodoTask;
import org.eclipse.cdt.internal.ui.wizards.dialogfields.ComboDialogField;
import org.eclipse.cdt.internal.ui.wizards.dialogfields.DialogField;
import org.eclipse.cdt.internal.ui.wizards.dialogfields.IDialogFieldListener;
import org.eclipse.cdt.internal.ui.wizards.dialogfields.LayoutUtil;
import org.eclipse.cdt.internal.ui.wizards.dialogfields.StringDialogField;
/**
* Dialog to enter a na new task tag
*/
public class TodoTaskInputDialog extends StatusDialog {
private class CompilerTodoTaskInputAdapter implements IDialogFieldListener {
public void dialogFieldChanged(DialogField field) {
doValidation();
}
}
private StringDialogField fNameDialogField;
private ComboDialogField fPriorityDialogField;
private List fExistingNames;
public TodoTaskInputDialog(Shell parent, TodoTask task, List existingEntries) {
super(parent);
fExistingNames= new ArrayList(existingEntries.size());
for (int i= 0; i < existingEntries.size(); i++) {
TodoTask curr= (TodoTask) existingEntries.get(i);
if (!curr.equals(task)) {
fExistingNames.add(curr.name);
}
}
if (task == null) {
setTitle(PreferencesMessages.getString("TodoTaskInputDialog.new.title")); //$NON-NLS-1$
} else {
setTitle(PreferencesMessages.getString("TodoTaskInputDialog.edit.title")); //$NON-NLS-1$
}
CompilerTodoTaskInputAdapter adapter= new CompilerTodoTaskInputAdapter();
fNameDialogField= new StringDialogField();
fNameDialogField.setLabelText(PreferencesMessages.getString("TodoTaskInputDialog.name.label")); //$NON-NLS-1$
fNameDialogField.setDialogFieldListener(adapter);
fNameDialogField.setText((task != null) ? task.name : ""); //$NON-NLS-1$
String[] items= new String[] {
PreferencesMessages.getString("TodoTaskInputDialog.priority.high"), //$NON-NLS-1$
PreferencesMessages.getString("TodoTaskInputDialog.priority.normal"), //$NON-NLS-1$
PreferencesMessages.getString("TodoTaskInputDialog.priority.low") //$NON-NLS-1$
};
fPriorityDialogField= new ComboDialogField(SWT.READ_ONLY);
fPriorityDialogField.setLabelText(PreferencesMessages.getString("TodoTaskInputDialog.priority.label")); //$NON-NLS-1$
fPriorityDialogField.setItems(items);
if (task != null) {
if (CCorePlugin.TRANSLATION_TASK_PRIORITY_HIGH.equals(task.priority)) {
fPriorityDialogField.selectItem(0);
} else if (CCorePlugin.TRANSLATION_TASK_PRIORITY_NORMAL.equals(task.priority)) {
fPriorityDialogField.selectItem(1);
} else {
fPriorityDialogField.selectItem(2);
}
} else {
fPriorityDialogField.selectItem(1);
}
}
public TodoTask getResult() {
TodoTask task= new TodoTask();
task.name= fNameDialogField.getText().trim();
switch (fPriorityDialogField.getSelectionIndex()) {
case 0 :
task.priority= CCorePlugin.TRANSLATION_TASK_PRIORITY_HIGH;
break;
case 1 :
task.priority= CCorePlugin.TRANSLATION_TASK_PRIORITY_NORMAL;
break;
default :
task.priority= CCorePlugin.TRANSLATION_TASK_PRIORITY_LOW;
break;
}
return task;
}
protected Control createDialogArea(Composite parent) {
Composite composite= (Composite) super.createDialogArea(parent);
Composite inner= new Composite(composite, SWT.NONE);
GridLayout layout= new GridLayout();
layout.marginHeight= 0;
layout.marginWidth= 0;
layout.numColumns= 2;
inner.setLayout(layout);
fNameDialogField.doFillIntoGrid(inner, 2);
fPriorityDialogField.doFillIntoGrid(inner, 2);
LayoutUtil.setHorizontalGrabbing(fNameDialogField.getTextControl(null));
LayoutUtil.setWidthHint(fNameDialogField.getTextControl(null), convertWidthInCharsToPixels(45));
fNameDialogField.postSetFocusOnDialogField(parent.getDisplay());
applyDialogFont(composite);
return composite;
}
private void doValidation() {
StatusInfo status= new StatusInfo();
String newText= fNameDialogField.getText();
if (newText.length() == 0) {
status.setError(PreferencesMessages.getString("TodoTaskInputDialog.error.enterName")); //$NON-NLS-1$
} else {
if (newText.indexOf(',') != -1) {
status.setError(PreferencesMessages.getString("TodoTaskInputDialog.error.comma")); //$NON-NLS-1$
} else if (fExistingNames.contains(newText)) {
status.setError(PreferencesMessages.getString("TodoTaskInputDialog.error.entryExists")); //$NON-NLS-1$
} else if (Character.isWhitespace(newText.charAt(0)) || Character.isWhitespace(newText.charAt(newText.length() - 1))) {
status.setError(PreferencesMessages.getString("TodoTaskInputDialog.error.noSpace")); //$NON-NLS-1$
}
}
updateStatus(status);
}
/*
* @see org.eclipse.jface.window.Window#configureShell(Shell)
*/
protected void configureShell(Shell newShell) {
super.configureShell(newShell);
WorkbenchHelp.setHelp(newShell, ICHelpContextIds.TODO_TASK_INPUT_DIALOG);
}
}

View file

@ -0,0 +1,99 @@
/*******************************************************************************
* Copyright (c) 2000, 2003 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Common Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/cpl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.internal.ui.preferences;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.preference.PreferencePage;
import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.IWorkbenchPreferencePage;
import org.eclipse.ui.help.WorkbenchHelp;
import org.eclipse.cdt.internal.ui.ICHelpContextIds;
import org.eclipse.cdt.ui.CUIPlugin;
import org.eclipse.cdt.internal.ui.dialogs.StatusUtil;
import org.eclipse.cdt.internal.ui.wizards.IStatusChangeListener;
/*
* The page to configure the compiler options.
*/
public class TodoTaskPreferencePage extends PreferencePage implements IWorkbenchPreferencePage, IStatusChangeListener {
public static final String ID= "org.eclipse.cdt.ui.propertyPages.TodoTaskPropertyPage"; //$NON-NLS-1$
private TodoTaskConfigurationBlock fConfigurationBlock;
public TodoTaskPreferencePage() {
setPreferenceStore(CUIPlugin.getDefault().getPreferenceStore());
//setDescription(PreferencesMessages.getString("TodoTaskPreferencePage.description")); //$NON-NLS-1$
// only used when page is shown programatically
setTitle(PreferencesMessages.getString("TodoTaskPreferencePage.title")); //$NON-NLS-1$
fConfigurationBlock= new TodoTaskConfigurationBlock(this, null);
}
/*
* @see IWorkbenchPreferencePage#init(org.eclipse.ui.IWorkbench)
*/
public void init(IWorkbench workbench) {
}
/*
* @see PreferencePage#createControl(Composite)
*/
public void createControl(Composite parent) {
// added for 1GEUGE6: ITPJUI:WIN2000 - Help is the same on all preference pages
super.createControl(parent);
WorkbenchHelp.setHelp(getControl(), ICHelpContextIds.TODO_TASK_PREFERENCE_PAGE);
}
/*
* @see PreferencePage#createContents(Composite)
*/
protected Control createContents(Composite parent) {
Control result= fConfigurationBlock.createContents(parent);
Dialog.applyDialogFont(result);
return result;
}
/*
* @see IPreferencePage#performOk()
*/
public boolean performOk() {
if (!fConfigurationBlock.performOk(true)) {
return false;
}
return super.performOk();
}
/*
* @see PreferencePage#performDefaults()
*/
protected void performDefaults() {
fConfigurationBlock.performDefaults();
super.performDefaults();
}
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.ui.wizards.IStatusChangeListener#statusChanged(org.eclipse.core.runtime.IStatus)
*/
public void statusChanged(IStatus status) {
setValid(!status.matches(IStatus.ERROR));
StatusUtil.applyToStatusLine(this, status);
}
}

View file

@ -0,0 +1,219 @@
/*******************************************************************************
* Copyright (c) 2000, 2003 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Common Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/cpl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.internal.ui.preferences;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.BusyIndicator;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.jface.dialogs.ControlEnableState;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.preference.IPreferenceNode;
import org.eclipse.jface.preference.IPreferencePage;
import org.eclipse.jface.preference.PreferenceDialog;
import org.eclipse.jface.preference.PreferenceManager;
import org.eclipse.jface.preference.PreferenceNode;
import org.eclipse.ui.dialogs.PropertyPage;
import org.eclipse.ui.help.WorkbenchHelp;
import org.eclipse.cdt.core.model.ICElement;
import org.eclipse.cdt.core.model.ICProject;
import org.eclipse.cdt.internal.ui.ICHelpContextIds;
import org.eclipse.cdt.internal.ui.dialogs.StatusInfo;
import org.eclipse.cdt.internal.ui.dialogs.StatusUtil;
import org.eclipse.cdt.internal.ui.wizards.IStatusChangeListener;
import org.eclipse.cdt.internal.ui.wizards.dialogfields.DialogField;
import org.eclipse.cdt.internal.ui.wizards.dialogfields.IDialogFieldListener;
import org.eclipse.cdt.internal.ui.wizards.dialogfields.LayoutUtil;
import org.eclipse.cdt.internal.ui.wizards.dialogfields.SelectionButtonDialogField;
/**
* Property page used to configure project specific task tags settings
*/
public class TodoTaskPropertyPage extends PropertyPage {
private TodoTaskConfigurationBlock fConfigurationBlock;
private Control fConfigurationBlockControl;
private ControlEnableState fBlockEnableState;
private SelectionButtonDialogField fUseWorkspaceSettings;
private SelectionButtonDialogField fChangeWorkspaceSettings;
private SelectionButtonDialogField fUseProjectSettings;
private IStatus fBlockStatus;
public TodoTaskPropertyPage() {
fBlockStatus= new StatusInfo();
fBlockEnableState= null;
IDialogFieldListener listener= new IDialogFieldListener() {
public void dialogFieldChanged(DialogField field) {
doDialogFieldChanged(field);
}
};
fUseWorkspaceSettings= new SelectionButtonDialogField(SWT.RADIO);
fUseWorkspaceSettings.setDialogFieldListener(listener);
fUseWorkspaceSettings.setLabelText(PreferencesMessages.getString("TodoTaskPropertyPage.useworkspacesettings.label")); //$NON-NLS-1$
fChangeWorkspaceSettings= new SelectionButtonDialogField(SWT.PUSH);
fChangeWorkspaceSettings.setLabelText(PreferencesMessages.getString("TodoTaskPropertyPage.useworkspacesettings.change")); //$NON-NLS-1$
fChangeWorkspaceSettings.setDialogFieldListener(listener);
fUseWorkspaceSettings.attachDialogField(fChangeWorkspaceSettings);
fUseProjectSettings= new SelectionButtonDialogField(SWT.RADIO);
fUseProjectSettings.setDialogFieldListener(listener);
fUseProjectSettings.setLabelText(PreferencesMessages.getString("TodoTaskPropertyPage.useprojectsettings.label")); //$NON-NLS-1$
}
/*
* @see org.eclipse.jface.dialogs.IDialogPage#createControl(org.eclipse.swt.widgets.Composite)
*/
public void createControl(Composite parent) {
super.createControl(parent);
WorkbenchHelp.setHelp(getControl(), ICHelpContextIds.TODO_TASK_PROPERTY_PAGE);
}
/*
* @see org.eclipse.jface.preference.IPreferencePage#createContents(Composite)
*/
protected Control createContents(Composite parent) {
IStatusChangeListener listener= new IStatusChangeListener() {
public void statusChanged(IStatus status) {
fBlockStatus= status;
doStatusChanged();
}
};
fConfigurationBlock= new TodoTaskConfigurationBlock(listener, getProject());
Composite composite= new Composite(parent, SWT.NONE);
GridLayout layout= new GridLayout();
layout.marginHeight= 0;
layout.marginWidth= 0;
layout.numColumns= 1;
composite.setLayout(layout);
fUseWorkspaceSettings.doFillIntoGrid(composite, 1);
LayoutUtil.setHorizontalGrabbing(fUseWorkspaceSettings.getSelectionButton(null));
fChangeWorkspaceSettings.doFillIntoGrid(composite, 1);
GridData data= (GridData) fChangeWorkspaceSettings.getSelectionButton(null).getLayoutData();
data.horizontalIndent= convertWidthInCharsToPixels(3);
data.horizontalAlignment= GridData.BEGINNING;
fUseProjectSettings.doFillIntoGrid(composite, 1);
data= new GridData(GridData.HORIZONTAL_ALIGN_FILL | GridData.VERTICAL_ALIGN_FILL );
data.horizontalSpan= 1;
data.horizontalIndent= convertWidthInCharsToPixels(2);
fConfigurationBlockControl= fConfigurationBlock.createContents(composite);
fConfigurationBlockControl.setLayoutData(data);
boolean useProjectSettings= fConfigurationBlock.hasProjectSpecificOptions();
fUseProjectSettings.setSelection(useProjectSettings);
fUseWorkspaceSettings.setSelection(!useProjectSettings);
updateEnableState();
Dialog.applyDialogFont(composite);
return composite;
}
private boolean useProjectSettings() {
return fUseProjectSettings.isSelected();
}
private void doDialogFieldChanged(DialogField field) {
if (field == fChangeWorkspaceSettings) {
TodoTaskPreferencePage page= new TodoTaskPreferencePage();
showPreferencePage(TodoTaskPreferencePage.ID, page);
} else {
updateEnableState();
doStatusChanged();
}
}
/**
* Method statusChanged.
*/
private void doStatusChanged() {
updateStatus(useProjectSettings() ? fBlockStatus : new StatusInfo());
}
/**
* Method getProject.
*/
private ICProject getProject() {
return (ICProject) getElement().getAdapter(ICElement.class);
}
private void updateEnableState() {
if (useProjectSettings()) {
if (fBlockEnableState != null) {
fBlockEnableState.restore();
fBlockEnableState= null;
}
} else {
if (fBlockEnableState == null) {
fBlockEnableState= ControlEnableState.disable(fConfigurationBlockControl);
}
}
}
/*
* @see org.eclipse.jface.preference.IPreferencePage#performDefaults()
*/
protected void performDefaults() {
if (useProjectSettings()) {
fUseProjectSettings.setSelection(false);
fUseWorkspaceSettings.setSelection(true);
fConfigurationBlock.performDefaults();
}
super.performDefaults();
}
/*
* @see org.eclipse.jface.preference.IPreferencePage#performOk()
*/
public boolean performOk() {
return fConfigurationBlock.performOk(useProjectSettings());
}
private void updateStatus(IStatus status) {
setValid(!status.matches(IStatus.ERROR));
StatusUtil.applyToStatusLine(this, status);
}
private boolean showPreferencePage(String id, IPreferencePage page) {
final IPreferenceNode targetNode = new PreferenceNode(id, page);
PreferenceManager manager = new PreferenceManager();
manager.addToRoot(targetNode);
final PreferenceDialog dialog = new PreferenceDialog(getShell(), manager);
final boolean [] result = new boolean[] { false };
BusyIndicator.showWhile(getShell().getDisplay(), new Runnable() {
public void run() {
dialog.create();
dialog.setMessage(targetNode.getLabelText());
result[0]= (dialog.open() == PreferenceDialog.OK);
}
});
return result[0];
}
}

View file

@ -0,0 +1,153 @@
/*******************************************************************************
* Copyright (c) 2000, 2003 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Common Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/cpl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.internal.ui.text;
import java.util.ArrayList;
import java.util.List;
import java.util.StringTokenizer;
import org.eclipse.core.runtime.Preferences;
import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.internal.ui.text.IColorManager;
import org.eclipse.cdt.internal.ui.text.ICColorConstants;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.text.rules.IToken;
import org.eclipse.jface.text.rules.IWordDetector;
import org.eclipse.jface.text.rules.Token;
import org.eclipse.jface.text.rules.WordRule;
import org.eclipse.jface.util.PropertyChangeEvent;
/**
* CCommentScanner.java
*/
public class CCommentScanner extends AbstractCScanner
{
private static class TaskTagDetector implements IWordDetector {
public boolean isWordStart(char c) {
return Character.isLetter(c);
}
public boolean isWordPart(char c) {
return Character.isLetter(c);
}
};
private class TaskTagRule extends WordRule {
private IToken fToken;
public TaskTagRule(IToken token) {
super(new TaskTagDetector(), Token.UNDEFINED);
fToken= token;
}
public void clearTaskTags() {
fWords.clear();
}
public void addTaskTags(String value) {
String[] tasks= split(value, ","); //$NON-NLS-1$
for (int i= 0; i < tasks.length; i++) {
if (tasks[i].length() > 0) {
addWord(tasks[i], fToken);
}
}
}
private String[] split(String value, String delimiters) {
StringTokenizer tokenizer= new StringTokenizer(value, delimiters);
int size= tokenizer.countTokens();
String[] tokens= new String[size];
int i= 0;
while (i < size)
tokens[i++]= tokenizer.nextToken();
return tokens;
}
}
private static final String TRANSLATION_TASK_TAGS= CCorePlugin.TRANSLATION_TASK_TAGS;
protected static final String TASK_TAG= ICColorConstants.TASK_TAG;
private TaskTagRule fTaskTagRule;
private Preferences fCorePreferenceStore;
private String fDefaultTokenProperty;
private String[] fTokenProperties;
public CCommentScanner(IColorManager manager, IPreferenceStore store, Preferences coreStore, String defaultTokenProperty) {
this(manager, store, coreStore, defaultTokenProperty, new String[] { defaultTokenProperty, TASK_TAG });
}
public CCommentScanner(IColorManager manager, IPreferenceStore store, Preferences coreStore, String defaultTokenProperty, String[] tokenProperties) {
super(manager, store);
fCorePreferenceStore= coreStore;
fDefaultTokenProperty= defaultTokenProperty;
fTokenProperties= tokenProperties;
initialize();
}
/*
* @see AbstractCScanner#createRules()
*/
protected List createRules() {
List list= new ArrayList();
if (fCorePreferenceStore != null) {
// Add rule for Task Tags.
fTaskTagRule= new TaskTagRule(getToken(TASK_TAG));
String tasks= fCorePreferenceStore.getString(TRANSLATION_TASK_TAGS);
fTaskTagRule.addTaskTags(tasks);
list.add(fTaskTagRule);
}
setDefaultReturnToken(getToken(fDefaultTokenProperty));
return list;
}
/*
* @see org.eclipse.cdt.internal.ui.text.AbstractJavaScanner#affectsBehavior(org.eclipse.jface.util.PropertyChangeEvent)
*/
public boolean affectsBehavior(PropertyChangeEvent event) {
return event.getProperty().equals(TRANSLATION_TASK_TAGS) || super.affectsBehavior(event);
}
/*
* @see org.eclipse.cdt.internal.ui.text.AbstractJavaScanner#adaptToPreferenceChange(org.eclipse.jface.util.PropertyChangeEvent)
*/
public void adaptToPreferenceChange(PropertyChangeEvent event) {
if (fTaskTagRule != null && event.getProperty().equals(TRANSLATION_TASK_TAGS)) {
Object value= event.getNewValue();
if (value instanceof String) {
fTaskTagRule.clearTaskTags();
fTaskTagRule.addTaskTags((String) value);
}
} else if (super.affectsBehavior(event)) {
super.adaptToPreferenceChange(event);
}
}
/*
* @see org.eclipse.cdt.internal.ui.text.AbstractJavaScanner#getTokenProperties()
*/
protected String[] getTokenProperties() {
return fTokenProperties;
}
}

View file

@ -1,150 +0,0 @@
package org.eclipse.cdt.internal.ui.text;
/*
* (c) Copyright IBM Corp. 2000, 2001.
* All Rights Reserved.
*/
import org.eclipse.jface.text.rules.ICharacterScanner;
import org.eclipse.jface.text.rules.IRule;
import org.eclipse.jface.text.rules.IToken;
import org.eclipse.jface.text.rules.Token;
import org.eclipse.jface.util.Assert;
/**
* Implementation of <code>IRule</code> for C code scanning.
* Optimized to partition C documents
* Is is capable of detecting a pattern which begins with a given starting
* sequence and ends with a given ending sequence. If the ending sequence is
* not specified, it can be either end of line, end or file, or both. Additionally,
* the pattern can be constrained to begin in a certain column.
*/
public class CMultilineCommentScanner implements IRule {
protected static final int UNDEFINED= -1;
/** The token to be returned on success */
protected IToken fToken;
/** The pattern's escape character */
protected char fEscapeCharacter;
/** Indicates whether end of line termines the pattern */
protected boolean fBreaksOnEOL;
/**
* Creates a rule for the given starting and ending sequence.
* When these sequences are detected the rule will return the specified token.
* Alternatively, the sequence can also be ended by the end of the line.
* Any character which follows the given escapeCharacter will be ignored.
*
* @param startSequence the pattern's start sequence
* @param endSequence the pattern's end sequence, <code>null</code> is a legal value
* @param token the token which will be returned on success
* @param escapeCharacter any character following this one will be ignored
* @param indicates whether the end of the line also termines the pattern
*/
public CMultilineCommentScanner(IToken token, char escapeCharacter, boolean breaksOnEOL) {
Assert.isNotNull(token);
fToken= token;
fEscapeCharacter= escapeCharacter;
fBreaksOnEOL= breaksOnEOL;
}
/**
* Returns whether the end sequence was detected. As the pattern can be considered
* ended by a line delimiter, the result of this method is <code>true</code> if the
* rule breaks on the end of the line, or if the EOF character is read.
*
* @param scanner the character scanner to be used
* @return <code>true</code> if the end sequence has been detected
*/
protected boolean endSequenceDetected(ICharacterScanner scanner) {
int c;
//char[][] delimiters= scanner.getLegalLineDelimiters();
while ((c= scanner.read()) != ICharacterScanner.EOF) {
if (c == fEscapeCharacter) {
// Skip the escaped character.
scanner.read();
} else if (c == '*') {
c = scanner.read();
if(c == '/') {
return true;
}
scanner.unread();
// Check if the specified end sequence has been found.
//} else if (fBreaksOnEOL) {
// Check for end of line since it can be used to terminate the pattern.
//for (int i= 0; i < delimiters.length; i++) {
// if (c == delimiters[i][0] && sequenceDetected(scanner, delimiters[i], false))
// return true;
//}
}
}
scanner.unread();
return true;
}
/*
* @see IRule#evaluate
*/
public IToken evaluate(ICharacterScanner scanner) {
int c= scanner.read();
if (c == '/') {
if((c= scanner.read()) == '*') {
endSequenceDetected(scanner);
return fToken;
}
scanner.unread();
}
scanner.unread();
return Token.UNDEFINED;
}
/**
* Returns whether the next characters to be read by the character scanner
* are an exact match with the given sequence. No escape characters are allowed
* within the sequence. If specified the sequence is considered to be found
* when reading the EOF character.
*
* @param scanner the character scanner to be used
* @param sequence the sequence to be detected
* @param eofAllowed indicated whether EOF terminates the pattern
* @return <code>true</code> if the given sequence has been detected
*/
protected boolean sequenceDetected(ICharacterScanner scanner, char[] sequence, boolean eofAllowed) {
for (int i= 1; i < sequence.length; i++) {
int c= scanner.read();
if (c == ICharacterScanner.EOF && eofAllowed) {
return true;
} else if (c != sequence[i]) {
// Non-matching character detected, rewind the scanner back to the start.
scanner.unread();
for (int j= i-1; j > 0; j--)
scanner.unread();
return false;
}
}
return true;
}
/**
* Sets a column constraint for this rule. If set, the rule's token
* will only be returned if the pattern is detected starting at the
* specified column. If the column is smaller then 0, the column
* constraint is considered removed.
*
* @param column the column in which the pattern starts
*/
public void setColumnConstraint(int column) {
if (column < 0)
column= UNDEFINED;
//fColumn= column;
}
}

View file

@ -120,7 +120,6 @@ public class CPartitionScanner extends RuleBasedPartitionScanner {
// Add rules for multi-line comments. // Add rules for multi-line comments.
rules.add(new MultiLineRule("/*", "*/", comment)); rules.add(new MultiLineRule("/*", "*/", comment));
//rules.add(new CMultilineCommentScanner(comment, (char)0, false));
IPredicateRule[] result= new IPredicateRule[rules.size()]; IPredicateRule[] result= new IPredicateRule[rules.size()];
rules.toArray(result); rules.toArray(result);

View file

@ -8,6 +8,8 @@ package org.eclipse.cdt.internal.ui.text;
import org.eclipse.cdt.internal.ui.text.util.CColorManager; import org.eclipse.cdt.internal.ui.text.util.CColorManager;
import org.eclipse.cdt.ui.CUIPlugin; import org.eclipse.cdt.ui.CUIPlugin;
import org.eclipse.core.runtime.Preferences;
import org.eclipse.jface.preference.IPreferenceStore; import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.text.IDocumentPartitioner; import org.eclipse.jface.text.IDocumentPartitioner;
import org.eclipse.jface.text.rules.DefaultPartitioner; import org.eclipse.jface.text.rules.DefaultPartitioner;
@ -23,10 +25,13 @@ import org.eclipse.jface.util.PropertyChangeEvent;
*/ */
public class CTextTools { public class CTextTools {
private class PreferenceListener implements IPropertyChangeListener { private class PreferenceListener implements IPropertyChangeListener, Preferences.IPropertyChangeListener {
public void propertyChange(PropertyChangeEvent event) { public void propertyChange(PropertyChangeEvent event) {
adaptToPreferenceChange(event); adaptToPreferenceChange(event);
} }
public void propertyChange(Preferences.PropertyChangeEvent event) {
adaptToPreferenceChange(new PropertyChangeEvent(event.getSource(), event.getProperty(), event.getOldValue(), event.getNewValue()));
}
}; };
/** The color manager */ /** The color manager */
@ -38,14 +43,16 @@ public class CTextTools {
/** The C partitions scanner */ /** The C partitions scanner */
private FastCPartitionScanner fPartitionScanner; private FastCPartitionScanner fPartitionScanner;
/** The Java multiline comment scanner */ /** The Java multiline comment scanner */
private SingleTokenCScanner fMultilineCommentScanner; private CCommentScanner fMultilineCommentScanner;
/** The Java singleline comment scanner */ /** The Java singleline comment scanner */
private SingleTokenCScanner fSinglelineCommentScanner; private CCommentScanner fSinglelineCommentScanner;
/** The Java string scanner */ /** The Java string scanner */
private SingleTokenCScanner fStringScanner; private SingleTokenCScanner fStringScanner;
/** The preference store */ /** The preference store */
private IPreferenceStore fPreferenceStore; private IPreferenceStore fPreferenceStore;
/** The core preference store */
private Preferences fCorePreferenceStore;
/** The preference change listener */ /** The preference change listener */
private PreferenceListener fPreferenceListener= new PreferenceListener(); private PreferenceListener fPreferenceListener= new PreferenceListener();
@ -55,19 +62,32 @@ public class CTextTools {
* and initializes all members of this collection. * and initializes all members of this collection.
*/ */
public CTextTools(IPreferenceStore store) { public CTextTools(IPreferenceStore store) {
this(store, null);
}
/**
* Creates a new C text tools collection and eagerly creates
* and initializes all members of this collection.
*/
public CTextTools(IPreferenceStore store, Preferences coreStore) {
if(store == null) { if(store == null) {
store = CUIPlugin.getDefault().getPreferenceStore(); store = CUIPlugin.getDefault().getPreferenceStore();
} }
fPreferenceStore = store; fPreferenceStore = store;
fPreferenceStore.addPropertyChangeListener(fPreferenceListener); fPreferenceStore.addPropertyChangeListener(fPreferenceListener);
fCorePreferenceStore= coreStore;
if (fCorePreferenceStore != null) {
fCorePreferenceStore.addPropertyChangeListener(fPreferenceListener);
}
fColorManager= new CColorManager(); fColorManager= new CColorManager();
fCodeScanner= new CCodeScanner(fColorManager, store); fCodeScanner= new CCodeScanner(fColorManager, store);
fCppCodeScanner= new CppCodeScanner(fColorManager, store); fCppCodeScanner= new CppCodeScanner(fColorManager, store);
fPartitionScanner= new FastCPartitionScanner(); fPartitionScanner= new FastCPartitionScanner();
fMultilineCommentScanner= new SingleTokenCScanner(fColorManager, store, ICColorConstants.C_MULTI_LINE_COMMENT); fMultilineCommentScanner= new CCommentScanner(fColorManager, store, coreStore, ICColorConstants.C_MULTI_LINE_COMMENT);
fSinglelineCommentScanner= new SingleTokenCScanner(fColorManager, store, ICColorConstants.C_SINGLE_LINE_COMMENT); fSinglelineCommentScanner= new CCommentScanner(fColorManager, store, coreStore, ICColorConstants.C_SINGLE_LINE_COMMENT);
fStringScanner= new SingleTokenCScanner(fColorManager, store, ICColorConstants.C_STRING); fStringScanner= new SingleTokenCScanner(fColorManager, store, ICColorConstants.C_STRING);
} }
@ -100,6 +120,12 @@ public class CTextTools {
if (fPreferenceStore != null) { if (fPreferenceStore != null) {
fPreferenceStore.removePropertyChangeListener(fPreferenceListener); fPreferenceStore.removePropertyChangeListener(fPreferenceListener);
fPreferenceStore= null; fPreferenceStore= null;
if (fCorePreferenceStore != null) {
fCorePreferenceStore.removePropertyChangeListener(fPreferenceListener);
fCorePreferenceStore= null;
}
fPreferenceListener= null; fPreferenceListener= null;
} }
} }
@ -151,18 +177,18 @@ public class CTextTools {
} }
/** /**
* Returns a scanner which is configured to scan Java multiline comments. * Returns a scanner which is configured to scan C multiline comments.
* *
* @return a Java multiline comment scanner * @return a C multiline comment scanner
*/ */
public RuleBasedScanner getMultilineCommentScanner() { public RuleBasedScanner getMultilineCommentScanner() {
return fMultilineCommentScanner; return fMultilineCommentScanner;
} }
/** /**
* Returns a scanner which is configured to scan Java singleline comments. * Returns a scanner which is configured to scan C singleline comments.
* *
* @return a Java singleline comment scanner * @return a C singleline comment scanner
*/ */
public RuleBasedScanner getSinglelineCommentScanner() { public RuleBasedScanner getSinglelineCommentScanner() {
return fSinglelineCommentScanner; return fSinglelineCommentScanner;

View file

@ -27,7 +27,11 @@ public interface ICColorConstants {
/* The color key for everthing in C code for which no other color is specified. */ /* The color key for everthing in C code for which no other color is specified. */
String C_DEFAULT= "c_default"; //$NON-NLS-1$ String C_DEFAULT= "c_default"; //$NON-NLS-1$
/**
* The color key for task tags in C comments
* (value <code>"c_comment_task_tag"</code>).
*/
String TASK_TAG= "c_comment_task_tag"; //$NON-NLS-1$
} }

View file

@ -13,7 +13,6 @@ import java.io.InputStreamReader;
import org.eclipse.cdt.core.model.CModelException; import org.eclipse.cdt.core.model.CModelException;
import org.eclipse.cdt.core.model.IBinary; import org.eclipse.cdt.core.model.IBinary;
import org.eclipse.cdt.core.model.ICElement; import org.eclipse.cdt.core.model.ICElement;
import org.eclipse.cdt.core.model.ISourceRange;
import org.eclipse.cdt.core.model.ISourceReference; import org.eclipse.cdt.core.model.ISourceReference;
import org.eclipse.cdt.core.model.ITranslationUnit; import org.eclipse.cdt.core.model.ITranslationUnit;
import org.eclipse.cdt.core.resources.FileStorage; import org.eclipse.cdt.core.resources.FileStorage;

View file

@ -1,9 +1,15 @@
/*******************************************************************************
* Copyright (c) 2000, 2003 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Common Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/cpl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.internal.ui.util; package org.eclipse.cdt.internal.ui.util;
/*
* (c) Copyright IBM Corp. 2000, 2001.
* All Rights Reserved.
*/
import org.eclipse.swt.SWT; import org.eclipse.swt.SWT;
import org.eclipse.swt.dnd.DragSource; import org.eclipse.swt.dnd.DragSource;
@ -16,7 +22,9 @@ import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Menu; import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.ScrollBar; import org.eclipse.swt.widgets.ScrollBar;
import org.eclipse.swt.widgets.Shell; import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.Widget; import org.eclipse.swt.widgets.Widget;
import org.eclipse.jface.dialogs.IDialogConstants; import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.resource.JFaceResources; import org.eclipse.jface.resource.JFaceResources;
import org.eclipse.jface.util.Assert; import org.eclipse.jface.util.Assert;
@ -101,6 +109,14 @@ public class SWTUtil {
} }
} }
public static int getTableHeightHint(Table table, int rows) {
if (table.getFont().equals(JFaceResources.getDefaultFont()))
table.setFont(JFaceResources.getDialogFont());
int result= table.getItemHeight() * rows + table.getHeaderHeight();
if (table.getLinesVisible())
result+= table.getGridLineWidth() * (rows - 1);
return result;
}
} }

View file

@ -0,0 +1,23 @@
/*******************************************************************************
* Copyright (c) 2000, 2003 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Common Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/cpl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.internal.ui.wizards;
import org.eclipse.core.runtime.IStatus;
public interface IStatusChangeListener {
/**
* Notifies this listener that the given status has changed.
*
* @param status the new status
*/
void statusChanged(IStatus status);
}

View file

@ -0,0 +1,225 @@
/*******************************************************************************
* Copyright (c) 2000, 2003 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Common Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/cpl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.internal.ui.wizards.dialogfields;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Label;
/**
* Dialog field containing a label and a combo control.
*/
public class ComboDialogField extends DialogField {
private String fText;
private int fSelectionIndex;
private String[] fItems;
private Combo fComboControl;
private ModifyListener fModifyListener;
private int fFlags;
public ComboDialogField(int flags) {
super();
fText= ""; //$NON-NLS-1$
fItems= new String[0];
fFlags= flags;
fSelectionIndex= -1;
}
// ------- layout helpers
/*
* @see DialogField#doFillIntoGrid
*/
public Control[] doFillIntoGrid(Composite parent, int nColumns) {
assertEnoughColumns(nColumns);
Label label= getLabelControl(parent);
label.setLayoutData(gridDataForLabel(1));
Combo combo= getComboControl(parent);
combo.setLayoutData(gridDataForCombo(nColumns - 1));
return new Control[] { label, combo };
}
/*
* @see DialogField#getNumberOfControls
*/
public int getNumberOfControls() {
return 2;
}
protected static GridData gridDataForCombo(int span) {
GridData gd= new GridData();
gd.horizontalAlignment= GridData.FILL;
gd.grabExcessHorizontalSpace= false;
gd.horizontalSpan= span;
return gd;
}
// ------- focus methods
/*
* @see DialogField#setFocus
*/
public boolean setFocus() {
if (isOkToUse(fComboControl)) {
fComboControl.setFocus();
}
return true;
}
// ------- ui creation
/**
* Creates or returns the created combo control.
* @param parent The parent composite or <code>null</code> when the widget has
* already been created.
*/
public Combo getComboControl(Composite parent) {
if (fComboControl == null) {
assertCompositeNotNull(parent);
fModifyListener= new ModifyListener() {
public void modifyText(ModifyEvent e) {
doModifyText(e);
}
};
SelectionListener selectionListener= new SelectionListener() {
public void widgetSelected(SelectionEvent e) {
doSelectionChanged(e);
}
public void widgetDefaultSelected(SelectionEvent e) { };
};
fComboControl= new Combo(parent, fFlags);
// moved up due to 1GEUNW2
fComboControl.setItems(fItems);
if (fSelectionIndex != -1) {
fComboControl.select(fSelectionIndex);
} else {
fComboControl.setText(fText);
}
fComboControl.setFont(parent.getFont());
fComboControl.addModifyListener(fModifyListener);
fComboControl.addSelectionListener(selectionListener);
fComboControl.setEnabled(isEnabled());
}
return fComboControl;
}
private void doModifyText(ModifyEvent e) {
if (isOkToUse(fComboControl)) {
fText= fComboControl.getText();
fSelectionIndex= fComboControl.getSelectionIndex();
}
dialogFieldChanged();
}
private void doSelectionChanged(SelectionEvent e) {
if (isOkToUse(fComboControl)) {
fItems= fComboControl.getItems();
fText= fComboControl.getText();
fSelectionIndex= fComboControl.getSelectionIndex();
}
dialogFieldChanged();
}
// ------ enable / disable management
/*
* @see DialogField#updateEnableState
*/
protected void updateEnableState() {
super.updateEnableState();
if (isOkToUse(fComboControl)) {
fComboControl.setEnabled(isEnabled());
}
}
// ------ text access
/**
* Gets the combo items.
*/
public String[] getItems() {
return fItems;
}
/**
* Sets the combo items. Triggers a dialog-changed event.
*/
public void setItems(String[] items) {
fItems= items;
if (isOkToUse(fComboControl)) {
fComboControl.setItems(items);
}
dialogFieldChanged();
}
/**
* Gets the text.
*/
public String getText() {
return fText;
}
/**
* Sets the text. Triggers a dialog-changed event.
*/
public void setText(String text) {
fText= text;
if (isOkToUse(fComboControl)) {
fComboControl.setText(text);
} else {
dialogFieldChanged();
}
}
/**
* Selects an item.
*/
public void selectItem(int index) {
if (isOkToUse(fComboControl)) {
fComboControl.select(index);
} else {
if (index >= 0 && index < fItems.length) {
fText= fItems[index];
fSelectionIndex= index;
}
}
dialogFieldChanged();
}
public int getSelectionIndex() {
return fSelectionIndex;
}
/**
* Sets the text without triggering a dialog-changed event.
*/
public void setTextWithoutUpdate(String text) {
fText= text;
if (isOkToUse(fComboControl)) {
fComboControl.removeModifyListener(fModifyListener);
fComboControl.setText(text);
fComboControl.addModifyListener(fModifyListener);
}
}
}

View file

@ -0,0 +1,192 @@
/*******************************************************************************
* Copyright (c) 2000, 2003 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Common Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/cpl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.internal.ui.wizards.dialogfields;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.cdt.internal.ui.util.SWTUtil;
/**
* Dialog Field containing a single button such as a radio or checkbox button.
*/
public class SelectionButtonDialogField extends DialogField {
private Button fButton;
private boolean fIsSelected;
private DialogField[] fAttachedDialogFields;
private int fButtonStyle;
/**
* Creates a selection button.
* Allowed button styles: SWT.RADIO, SWT.CHECK, SWT.TOGGLE, SWT.PUSH
*/
public SelectionButtonDialogField(int buttonStyle) {
super();
fIsSelected= false;
fAttachedDialogFields= null;
fButtonStyle= buttonStyle;
}
/**
* Attaches a field to the selection state of the selection button.
* The attached field will be disabled if the selection button is not selected.
*/
public void attachDialogField(DialogField dialogField) {
attachDialogFields(new DialogField[] { dialogField });
}
/**
* Attaches fields to the selection state of the selection button.
* The attached fields will be disabled if the selection button is not selected.
*/
public void attachDialogFields(DialogField[] dialogFields) {
fAttachedDialogFields= dialogFields;
for (int i= 0; i < dialogFields.length; i++) {
dialogFields[i].setEnabled(fIsSelected);
}
}
/**
* Returns <code>true</code> is teh gived field is attached to the selection button.
*/
public boolean isAttached(DialogField editor) {
if (fAttachedDialogFields != null) {
for (int i=0; i < fAttachedDialogFields.length; i++) {
if (fAttachedDialogFields[i] == editor) {
return true;
}
}
}
return false;
}
// ------- layout helpers
/*
* @see DialogField#doFillIntoGrid
*/
public Control[] doFillIntoGrid(Composite parent, int nColumns) {
assertEnoughColumns(nColumns);
Button button= getSelectionButton(parent);
GridData gd= new GridData();
gd.horizontalSpan= nColumns;
gd.horizontalAlignment= GridData.FILL;
if (fButtonStyle == SWT.PUSH) {
gd.heightHint = SWTUtil.getButtonHeigthHint(button);
gd.widthHint = SWTUtil.getButtonWidthHint(button);
}
button.setLayoutData(gd);
return new Control[] { button };
}
/*
* @see DialogField#getNumberOfControls
*/
public int getNumberOfControls() {
return 1;
}
// ------- ui creation
/**
* Returns the selection button widget. When called the first time, the widget will be created.
* @param The parent composite when called the first time, or <code>null</code>
* after.
*/
public Button getSelectionButton(Composite group) {
if (fButton == null) {
assertCompositeNotNull(group);
fButton= new Button(group, fButtonStyle);
fButton.setFont(group.getFont());
fButton.setText(fLabelText);
fButton.setEnabled(isEnabled());
fButton.setSelection(fIsSelected);
fButton.addSelectionListener(new SelectionListener() {
public void widgetDefaultSelected(SelectionEvent e) {
doWidgetSelected(e);
}
public void widgetSelected(SelectionEvent e) {
doWidgetSelected(e);
}
});
}
return fButton;
}
private void doWidgetSelected(SelectionEvent e) {
if (isOkToUse(fButton)) {
changeValue(fButton.getSelection());
}
}
private void changeValue(boolean newState) {
if (fIsSelected != newState) {
fIsSelected= newState;
if (fAttachedDialogFields != null) {
boolean focusSet= false;
for (int i= 0; i < fAttachedDialogFields.length; i++) {
fAttachedDialogFields[i].setEnabled(fIsSelected);
if (fIsSelected && !focusSet) {
focusSet= fAttachedDialogFields[i].setFocus();
}
}
}
dialogFieldChanged();
} else if (fButtonStyle == SWT.PUSH) {
dialogFieldChanged();
}
}
// ------ model access
/**
* Returns the selection state of the button.
*/
public boolean isSelected() {
return fIsSelected;
}
/**
* Sets the selection state of the button.
*/
public void setSelection(boolean selected) {
changeValue(selected);
if (isOkToUse(fButton)) {
fButton.setSelection(selected);
}
}
// ------ enable / disable management
/*
* @see DialogField#updateEnableState
*/
protected void updateEnableState() {
super.updateEnableState();
if (isOkToUse(fButton)) {
fButton.setEnabled(isEnabled());
}
}
}

View file

@ -9,6 +9,7 @@ import java.text.MessageFormat;
import java.util.MissingResourceException; import java.util.MissingResourceException;
import java.util.ResourceBundle; import java.util.ResourceBundle;
import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.model.CoreModel; import org.eclipse.cdt.core.model.CoreModel;
import org.eclipse.cdt.core.model.ICElement; import org.eclipse.cdt.core.model.ICElement;
import org.eclipse.cdt.internal.ui.BuildConsoleManager; import org.eclipse.cdt.internal.ui.BuildConsoleManager;
@ -183,7 +184,7 @@ public class CUIPlugin extends AbstractUIPlugin {
*/ */
public CTextTools getTextTools() { public CTextTools getTextTools() {
if (fTextTools == null) if (fTextTools == null)
fTextTools = new CTextTools(); fTextTools = new CTextTools(getPreferenceStore(), CCorePlugin.getDefault().getPluginPreferences());
return fTextTools; return fTextTools;
} }
@ -192,7 +193,7 @@ public class CUIPlugin extends AbstractUIPlugin {
*/ */
public AsmTextTools getAsmTextTools() { public AsmTextTools getAsmTextTools() {
if (fAsmTextTools == null) if (fAsmTextTools == null)
fAsmTextTools = new AsmTextTools(); fAsmTextTools = new AsmTextTools(getPreferenceStore(), CCorePlugin.getDefault().getPluginPreferences());
return fAsmTextTools; return fAsmTextTools;
} }
@ -263,6 +264,8 @@ public class CUIPlugin extends AbstractUIPlugin {
*/ */
protected void initializeDefaultPreferences(final IPreferenceStore store) { protected void initializeDefaultPreferences(final IPreferenceStore store) {
super.initializeDefaultPreferences(store); super.initializeDefaultPreferences(store);
PreferenceConstants.initializeDefaultValues(store);
runUI(new Runnable() { runUI(new Runnable() {
public void run() { public void run() {
CPluginPreferencePage.initDefaults(store); CPluginPreferencePage.initDefaults(store);

View file

@ -4,7 +4,12 @@
*/ */
package org.eclipse.cdt.ui; package org.eclipse.cdt.ui;
import org.eclipse.swt.graphics.RGB;
import org.eclipse.jface.preference.IPreferenceStore; import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.preference.PreferenceConverter;
import org.eclipse.cdt.internal.ui.text.ICColorConstants;
/** /**
* Preference constants used in the JDT-UI preference store. Clients should only read the * Preference constants used in the JDT-UI preference store. Clients should only read the
@ -18,6 +23,12 @@ public class PreferenceConstants {
private PreferenceConstants() { private PreferenceConstants() {
} }
/**
* Preference key suffix for bold text style preference keys.
*/
public static final String EDITOR_BOLD_SUFFIX= "_bold"; //$NON-NLS-1$
/** /**
* A named preference that controls if comment stubs will be added * A named preference that controls if comment stubs will be added
* automatically to newly created types and methods. * automatically to newly created types and methods.
@ -52,6 +63,57 @@ public class PreferenceConstants {
*/ */
public static final String EDITOR_SHOW_SEGMENTS= "org.eclipse.cdt.ui.editor.showSegments"; //$NON-NLS-1$ public static final String EDITOR_SHOW_SEGMENTS= "org.eclipse.cdt.ui.editor.showSegments"; //$NON-NLS-1$
/**
* A named preference that holds the color used to render task tags.
* <p>
* Value is of type <code>String</code>. A RGB color value encoded as a string
* using class <code>PreferenceConverter</code>
* </p>
*
* @see org.eclipse.jface.resource.StringConverter
* @see org.eclipse.jface.preference.PreferenceConverter
*/
public final static String EDITOR_TASK_TAG_COLOR= ICColorConstants.TASK_TAG;
/**
* A named preference that controls whether task tags are rendered in bold.
* <p>
* Value is of type <code>Boolean</code>.
* </p>
*/
public final static String EDITOR_TASK_TAG_BOLD= ICColorConstants.TASK_TAG + EDITOR_BOLD_SUFFIX;
/**
* A named preference that controls whether the editor shows task indicators in text (squiggly lines).
* <p>
* Value is of type <code>Boolean</code>.
* </p>
*/
public final static String EDITOR_TASK_INDICATION= "taskIndication"; //$NON-NLS-1$
/**
* A named preference that holds the color used to render task indicators.
* <p>
* Value is of type <code>String</code>. A RGB color value encoded as a string
* using class <code>PreferenceConverter</code>
* </p>
*
* @see #EDITOR_TASK_INDICATION
* @see org.eclipse.jface.resource.StringConverter
* @see org.eclipse.jface.preference.PreferenceConverter
*/
public final static String EDITOR_TASK_INDICATION_COLOR= "taskIndicationColor"; //$NON-NLS-1$
/**
* A named preference that controls whether the overview ruler shows task
* indicators.
* <p>
* Value is of type <code>Boolean</code>.
* </p>
* @since 2.1
*/
public final static String EDITOR_TASK_INDICATION_IN_OVERVIEW_RULER= "taskIndicationInOverviewRuler"; //$NON-NLS-1$
/** /**
* Returns the JDT-UI preference store. * Returns the JDT-UI preference store.
* *
@ -60,4 +122,18 @@ public class PreferenceConstants {
public static IPreferenceStore getPreferenceStore() { public static IPreferenceStore getPreferenceStore() {
return CUIPlugin.getDefault().getPreferenceStore(); return CUIPlugin.getDefault().getPreferenceStore();
} }
/**
* Initializes the given preference store with the default values.
*
* @param store the preference store to be initialized
*/
public static void initializeDefaultValues(IPreferenceStore store) {
store.setDefault(PreferenceConstants.EDITOR_TASK_INDICATION, false);
PreferenceConverter.setDefault(store, PreferenceConstants.EDITOR_TASK_INDICATION_COLOR, new RGB(0, 128, 255));
store.setDefault(PreferenceConstants.EDITOR_TASK_INDICATION_IN_OVERVIEW_RULER, true);
PreferenceConverter.setDefault(store, PreferenceConstants.EDITOR_TASK_TAG_COLOR, new RGB(127, 159, 191));
store.setDefault(PreferenceConstants.EDITOR_TASK_TAG_BOLD, true);
}
} }