mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-06-06 17:26:01 +02:00
Bug 235586 - Code templates: Include guard not unique
Patch by Jens Elementhaler
This commit is contained in:
parent
415ff10013
commit
01968f4ebd
2 changed files with 162 additions and 38 deletions
|
@ -8,6 +8,7 @@
|
||||||
* Contributors:
|
* Contributors:
|
||||||
* Rational Software - initial implementation
|
* Rational Software - initial implementation
|
||||||
* Anton Leherbauer (Wind River Systems)
|
* Anton Leherbauer (Wind River Systems)
|
||||||
|
* Jens Elmenthaler (Verigy) - http://bugs.eclipse.org/235586
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
package org.eclipse.cdt.internal.corext.codemanipulation;
|
package org.eclipse.cdt.internal.corext.codemanipulation;
|
||||||
|
|
||||||
|
@ -15,6 +16,7 @@ import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
import org.eclipse.core.resources.IFile;
|
import org.eclipse.core.resources.IFile;
|
||||||
import org.eclipse.core.resources.IProject;
|
import org.eclipse.core.resources.IProject;
|
||||||
|
@ -44,6 +46,7 @@ import org.eclipse.text.edits.MultiTextEdit;
|
||||||
import org.eclipse.cdt.core.CCorePlugin;
|
import org.eclipse.cdt.core.CCorePlugin;
|
||||||
import org.eclipse.cdt.core.CCorePreferenceConstants;
|
import org.eclipse.cdt.core.CCorePreferenceConstants;
|
||||||
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.IBuffer;
|
import org.eclipse.cdt.core.model.IBuffer;
|
||||||
import org.eclipse.cdt.core.model.ICElement;
|
import org.eclipse.cdt.core.model.ICElement;
|
||||||
import org.eclipse.cdt.core.model.ICProject;
|
import org.eclipse.cdt.core.model.ICProject;
|
||||||
|
@ -89,7 +92,7 @@ public class StubUtility {
|
||||||
context.setVariable(CodeTemplateContextType.FILE_COMMENT, fileComment != null ? fileComment : ""); //$NON-NLS-1$
|
context.setVariable(CodeTemplateContextType.FILE_COMMENT, fileComment != null ? fileComment : ""); //$NON-NLS-1$
|
||||||
context.setVariable(CodeTemplateContextType.DECLARATIONS, declarations != null ? declarations : ""); //$NON-NLS-1$
|
context.setVariable(CodeTemplateContextType.DECLARATIONS, declarations != null ? declarations : ""); //$NON-NLS-1$
|
||||||
context.setVariable(CodeTemplateContextType.TYPENAME, new Path(tu.getElementName()).removeFileExtension().toString());
|
context.setVariable(CodeTemplateContextType.TYPENAME, new Path(tu.getElementName()).removeFileExtension().toString());
|
||||||
String includeGuardSymbol= generateIncludeGuardSymbol(tu.getElementName());
|
String includeGuardSymbol= generateIncludeGuardSymbol(tu.getElementName(), project);
|
||||||
context.setVariable(CodeTemplateContextType.INCLUDE_GUARD_SYMBOL, includeGuardSymbol != null ? includeGuardSymbol : ""); //$NON-NLS-1$
|
context.setVariable(CodeTemplateContextType.INCLUDE_GUARD_SYMBOL, includeGuardSymbol != null ? includeGuardSymbol : ""); //$NON-NLS-1$
|
||||||
|
|
||||||
String[] fullLine= { CodeTemplateContextType.FILE_COMMENT, CodeTemplateContextType.TYPE_COMMENT, CodeTemplateContextType.DECLARATIONS };
|
String[] fullLine= { CodeTemplateContextType.FILE_COMMENT, CodeTemplateContextType.TYPE_COMMENT, CodeTemplateContextType.DECLARATIONS };
|
||||||
|
@ -127,7 +130,8 @@ public class StubUtility {
|
||||||
FileTemplateContext context= new FileTemplateContext(template.getContextTypeId(), lineDelimiter);
|
FileTemplateContext context= new FileTemplateContext(template.getContextTypeId(), lineDelimiter);
|
||||||
String fileComment= getFileComment(file, lineDelimiter);
|
String fileComment= getFileComment(file, lineDelimiter);
|
||||||
context.setVariable(CodeTemplateContextType.FILE_COMMENT, fileComment != null ? fileComment : ""); //$NON-NLS-1$
|
context.setVariable(CodeTemplateContextType.FILE_COMMENT, fileComment != null ? fileComment : ""); //$NON-NLS-1$
|
||||||
String includeGuardSymbol= generateIncludeGuardSymbol(file.getName());
|
ICProject cproject = CoreModel.getDefault().create(file.getProject());
|
||||||
|
String includeGuardSymbol= generateIncludeGuardSymbol(file.getName(), cproject);
|
||||||
context.setVariable(CodeTemplateContextType.INCLUDE_GUARD_SYMBOL, includeGuardSymbol != null ? includeGuardSymbol : ""); //$NON-NLS-1$
|
context.setVariable(CodeTemplateContextType.INCLUDE_GUARD_SYMBOL, includeGuardSymbol != null ? includeGuardSymbol : ""); //$NON-NLS-1$
|
||||||
context.setResourceVariables(file);
|
context.setResourceVariables(file);
|
||||||
String[] fullLine= { CodeTemplateContextType.FILE_COMMENT };
|
String[] fullLine= { CodeTemplateContextType.FILE_COMMENT };
|
||||||
|
@ -475,7 +479,7 @@ public class StubUtility {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean doAddComments(ICProject project) {
|
public static boolean doAddComments(ICProject project) {
|
||||||
return Boolean.valueOf(PreferenceConstants.getPreference(PreferenceConstants.CODEGEN_ADD_COMMENTS, project)).booleanValue();
|
return PreferenceConstants.getPreference(PreferenceConstants.CODEGEN_ADD_COMMENTS, project, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Template getDefaultFileTemplate(ITranslationUnit tu) {
|
private static Template getDefaultFileTemplate(ITranslationUnit tu) {
|
||||||
|
@ -513,30 +517,78 @@ public class StubUtility {
|
||||||
return projectStore.findTemplateById(id);
|
return projectStore.findTemplateById(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String generateIncludeGuardSymbol(String fileName) {
|
private static int getIncludeGuardScheme(ICProject cproject) {
|
||||||
//TODO eventually make this a prefs option - filename pattern or
|
return PreferenceConstants.getPreference(
|
||||||
// unique id/incremental value
|
PreferenceConstants.CODE_TEMPLATES_INCLUDE_GUARD_SCHEME,
|
||||||
String name = fileName;
|
cproject,
|
||||||
if (name != null) {
|
PreferenceConstants.CODE_TEMPLATES_INCLUDE_GUARD_SCHEME_FILE_NAME);
|
||||||
//convert to upper case and remove invalid characters
|
}
|
||||||
//eg convert foo.h --> FOO_H_
|
|
||||||
StringBuffer buf = new StringBuffer();
|
private static String generateIncludeGuardSymbol(String fileName, ICProject cproject) {
|
||||||
// Do not do this, leading underscores are discourage by the std.
|
|
||||||
//buf.append('_');
|
int preferenceValue = getIncludeGuardScheme(cproject);
|
||||||
for (int i = 0; i < name.length(); ++i) {
|
|
||||||
char ch = name.charAt(i);
|
switch (preferenceValue) {
|
||||||
if (Character.isLetterOrDigit(ch)) {
|
case PreferenceConstants.CODE_TEMPLATES_INCLUDE_GUARD_SCHEME_FILE_NAME:
|
||||||
buf.append(Character.toUpperCase(ch));
|
if (fileName != null) {
|
||||||
} else if (ch == '.' || ch == '_') {
|
return generateIncludeGuardSymbolFromFileName(fileName);
|
||||||
buf.append('_');
|
} else {
|
||||||
}
|
return null;
|
||||||
}
|
}
|
||||||
buf.append('_');
|
|
||||||
return buf.toString();
|
case PreferenceConstants.CODE_TEMPLATES_INCLUDE_GUARD_SCHEME_UUID:
|
||||||
}
|
return generateIncludeGuardSymbolFromUUID();
|
||||||
return null;
|
|
||||||
|
default:
|
||||||
|
CUIPlugin.log("Unknown preference value " + preferenceValue + "for include guard scheme", null); //$NON-NLS-1$ //$NON-NLS-2$
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static String generateIncludeGuardSymbolFromFileName(String fileName) {
|
||||||
|
String name = fileName;
|
||||||
|
//convert to upper case and remove invalid characters
|
||||||
|
//eg convert foo.h --> FOO_H_
|
||||||
|
StringBuffer buf = new StringBuffer();
|
||||||
|
// Do not do this, leading underscores are discouraged by the std.
|
||||||
|
//buf.append('_');
|
||||||
|
for (int i = 0; i < name.length(); ++i) {
|
||||||
|
char ch = name.charAt(i);
|
||||||
|
if (Character.isLetterOrDigit(ch)) {
|
||||||
|
buf.append(Character.toUpperCase(ch));
|
||||||
|
} else if (ch == '.' || ch == '_') {
|
||||||
|
buf.append('_');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
buf.append('_');
|
||||||
|
return buf.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String generateIncludeGuardSymbolFromUUID() {
|
||||||
|
String uuid = UUID.randomUUID().toString();
|
||||||
|
|
||||||
|
// 1) Make sure the guard always starts with a letter.
|
||||||
|
// 2) Convert to upper case and remove invalid characters
|
||||||
|
//
|
||||||
|
// e.g. convert
|
||||||
|
// 067e6162-3b6f-4ae2-a171-2470b63dff00 to
|
||||||
|
// H067E6162-3b6F-4AE2-A171-2470B63DFF00
|
||||||
|
StringBuffer buf = new StringBuffer();
|
||||||
|
|
||||||
|
buf.append('H');
|
||||||
|
|
||||||
|
for (int i = 0; i < uuid.length(); ++i) {
|
||||||
|
char ch = uuid.charAt(i);
|
||||||
|
if (Character.isLetterOrDigit(ch)) {
|
||||||
|
buf.append(Character.toUpperCase(ch));
|
||||||
|
} else {
|
||||||
|
buf.append('_');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return buf.toString();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get a set of file templates for the given content types.
|
* Get a set of file templates for the given content types.
|
||||||
*
|
*
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
* Anton Leherbauer (Wind River Systems)
|
* Anton Leherbauer (Wind River Systems)
|
||||||
* Sergey Prigogin (Google)
|
* Sergey Prigogin (Google)
|
||||||
* Elazar Leibovich (IDF) - Code folding of compound statements (bug 174597)
|
* Elazar Leibovich (IDF) - Code folding of compound statements (bug 174597)
|
||||||
|
* Jens Elmenthaler (Verigy) - http://bugs.eclipse.org/235586
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
package org.eclipse.cdt.ui;
|
package org.eclipse.cdt.ui;
|
||||||
|
|
||||||
|
@ -18,6 +19,7 @@ import java.util.Locale;
|
||||||
|
|
||||||
import org.eclipse.core.resources.ProjectScope;
|
import org.eclipse.core.resources.ProjectScope;
|
||||||
import org.eclipse.core.runtime.preferences.DefaultScope;
|
import org.eclipse.core.runtime.preferences.DefaultScope;
|
||||||
|
import org.eclipse.core.runtime.preferences.IEclipsePreferences;
|
||||||
import org.eclipse.core.runtime.preferences.InstanceScope;
|
import org.eclipse.core.runtime.preferences.InstanceScope;
|
||||||
import org.eclipse.jface.action.Action;
|
import org.eclipse.jface.action.Action;
|
||||||
import org.eclipse.jface.preference.IPreferenceStore;
|
import org.eclipse.jface.preference.IPreferenceStore;
|
||||||
|
@ -1380,6 +1382,32 @@ public class PreferenceConstants {
|
||||||
*/
|
*/
|
||||||
public static final String SCALABILITY_CONTENT_ASSIST_AUTO_ACTIVATION = "scalability.contentAssistAutoActivation"; //$NON-NLS-1$
|
public static final String SCALABILITY_CONTENT_ASSIST_AUTO_ACTIVATION = "scalability.contentAssistAutoActivation"; //$NON-NLS-1$
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A named preference that controls how an include guard symbol is created.
|
||||||
|
* <p>
|
||||||
|
* Value is of type <code>Integer</code>.
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @since 5.1
|
||||||
|
*/
|
||||||
|
public static final String CODE_TEMPLATES_INCLUDE_GUARD_SCHEME = "codetemplates.includeGuardGenerationScheme"; //$NON-NLS-1$
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The value of <code>CODE_TEMPLATES_INCLUDE_GUARD_GENERATION_SCHEME</code>
|
||||||
|
* specifying that the include guard symbol is to be derived from the
|
||||||
|
* include file's name.
|
||||||
|
*
|
||||||
|
* @since 5.1
|
||||||
|
*/
|
||||||
|
public static final int CODE_TEMPLATES_INCLUDE_GUARD_SCHEME_FILE_NAME = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The value of <code>CODE_TEMPLATES_INCLUDE_GUARD_GENERATION_SCHEME</code>
|
||||||
|
* specifying that the include guard symbol is to be derived from a UUID.
|
||||||
|
*
|
||||||
|
* @since 5.1
|
||||||
|
*/
|
||||||
|
public static final int CODE_TEMPLATES_INCLUDE_GUARD_SCHEME_UUID = 1;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the CDT-UI preference store.
|
* Returns the CDT-UI preference store.
|
||||||
|
@ -1572,11 +1600,39 @@ public class PreferenceConstants {
|
||||||
store.setDefault(PreferenceConstants.SCALABILITY_SEMANTIC_HIGHLIGHT, false);
|
store.setDefault(PreferenceConstants.SCALABILITY_SEMANTIC_HIGHLIGHT, false);
|
||||||
store.setDefault(PreferenceConstants.SCALABILITY_PARSER_BASED_CONTENT_ASSIST, false);
|
store.setDefault(PreferenceConstants.SCALABILITY_PARSER_BASED_CONTENT_ASSIST, false);
|
||||||
store.setDefault(PreferenceConstants.SCALABILITY_CONTENT_ASSIST_AUTO_ACTIVATION, false);
|
store.setDefault(PreferenceConstants.SCALABILITY_CONTENT_ASSIST_AUTO_ACTIVATION, false);
|
||||||
|
|
||||||
|
//Code Templates
|
||||||
|
store.setDefault(PreferenceConstants.CODE_TEMPLATES_INCLUDE_GUARD_SCHEME,
|
||||||
|
CODE_TEMPLATES_INCLUDE_GUARD_SCHEME_FILE_NAME);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the node in the preference in the given context.
|
||||||
|
* @param key The preference key.
|
||||||
|
* @param project The current context or <code>null</code> if no context is available and the
|
||||||
|
* workspace setting should be taken. Note that passing <code>null</code> should
|
||||||
|
* be avoided.
|
||||||
|
* @return Returns the node matching the given context.
|
||||||
|
*/
|
||||||
|
private static IEclipsePreferences getPreferenceNode(String key, ICProject project) {
|
||||||
|
IEclipsePreferences node = null;
|
||||||
|
|
||||||
|
if (project != null) {
|
||||||
|
node = new ProjectScope(project.getProject()).getNode(CUIPlugin.PLUGIN_ID);
|
||||||
|
if (node.get(key, null) != null) {
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
node = new InstanceScope().getNode(CUIPlugin.PLUGIN_ID);
|
||||||
|
if (node.get(key, null) != null) {
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
|
return new DefaultScope().getNode(CUIPlugin.PLUGIN_ID);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the value for the given key in the given context.
|
* Returns the string value for the given key in the given context.
|
||||||
* @param key The preference key
|
* @param key The preference key
|
||||||
* @param project The current context or <code>null</code> if no context is available and the
|
* @param project The current context or <code>null</code> if no context is available and the
|
||||||
* workspace setting should be taken. Note that passing <code>null</code> should
|
* workspace setting should be taken. Note that passing <code>null</code> should
|
||||||
|
@ -1585,20 +1641,36 @@ public class PreferenceConstants {
|
||||||
* @since 5.0
|
* @since 5.0
|
||||||
*/
|
*/
|
||||||
public static String getPreference(String key, ICProject project) {
|
public static String getPreference(String key, ICProject project) {
|
||||||
String val;
|
return getPreferenceNode(key, project).get(key, null);
|
||||||
if (project != null) {
|
|
||||||
val= new ProjectScope(project.getProject()).getNode(CUIPlugin.PLUGIN_ID).get(key, null);
|
|
||||||
if (val != null) {
|
|
||||||
return val;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
val= new InstanceScope().getNode(CUIPlugin.PLUGIN_ID).get(key, null);
|
|
||||||
if (val != null) {
|
|
||||||
return val;
|
|
||||||
}
|
|
||||||
return new DefaultScope().getNode(CUIPlugin.PLUGIN_ID).get(key, null);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the integer value for the given key in the given context.
|
||||||
|
* @param key The preference key
|
||||||
|
* @param project The current context or <code>null</code> if no context is available and the
|
||||||
|
* workspace setting should be taken. Note that passing <code>null</code> should
|
||||||
|
* be avoided.
|
||||||
|
* @param defaultValue The default value if not specified in the preferences.
|
||||||
|
* @return Returns the current value for the string.
|
||||||
|
* @since 5.1
|
||||||
|
*/
|
||||||
|
public static int getPreference(String key, ICProject project, int defaultValue) {
|
||||||
|
return getPreferenceNode(key, project).getInt(key, defaultValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the boolean value for the given key in the given context.
|
||||||
|
* @param key The preference key
|
||||||
|
* @param project The current context or <code>null</code> if no context is available and the
|
||||||
|
* workspace setting should be taken. Note that passing <code>null</code> should
|
||||||
|
* be avoided.
|
||||||
|
* @param defaultValue The default value if not specified in the preferences.
|
||||||
|
* @return Returns the current value for the string.
|
||||||
|
* @since 5.1
|
||||||
|
*/
|
||||||
|
public static boolean getPreference(String key, ICProject project, boolean defaultValue) {
|
||||||
|
return getPreferenceNode(key, project).getBoolean(key, defaultValue);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the default value and fires a property
|
* Sets the default value and fires a property
|
||||||
|
|
Loading…
Add table
Reference in a new issue