diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/rewrite/changegenerator/ChangeGeneratorTest.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/rewrite/changegenerator/ChangeGeneratorTest.java index 95d96c18276..287ecc73416 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/rewrite/changegenerator/ChangeGeneratorTest.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/rewrite/changegenerator/ChangeGeneratorTest.java @@ -19,13 +19,13 @@ import org.eclipse.cdt.core.index.IIndexManager; import org.eclipse.cdt.core.parser.tests.rewrite.TestHelper; import org.eclipse.cdt.core.tests.BaseTestFramework; import org.eclipse.cdt.internal.core.dom.rewrite.ASTModificationStore; -import org.eclipse.cdt.internal.core.dom.rewrite.changegenerator.CTextFileChange; import org.eclipse.cdt.internal.core.dom.rewrite.changegenerator.ChangeGenerator; import org.eclipse.core.runtime.NullProgressMonitor; import org.eclipse.core.runtime.Path; import org.eclipse.jface.text.Document; import org.eclipse.ltk.core.refactoring.Change; import org.eclipse.ltk.core.refactoring.CompositeChange; +import org.eclipse.ltk.core.refactoring.TextFileChange; public abstract class ChangeGeneratorTest extends BaseTestFramework { @@ -63,8 +63,8 @@ public abstract class ChangeGeneratorTest extends BaseTestFramework { changegenartor.generateChange(unit); Document doc = new Document(source); for(Change curChange : ((CompositeChange)changegenartor.getChange()).getChildren()){ - if (curChange instanceof CTextFileChange) { - CTextFileChange textChange = (CTextFileChange) curChange; + if (curChange instanceof TextFileChange) { + TextFileChange textChange = (TextFileChange) curChange; textChange.getEdit().apply(doc); } } diff --git a/core/org.eclipse.cdt.core/META-INF/MANIFEST.MF b/core/org.eclipse.cdt.core/META-INF/MANIFEST.MF index 61acc88498b..3a60c567de9 100644 --- a/core/org.eclipse.cdt.core/META-INF/MANIFEST.MF +++ b/core/org.eclipse.cdt.core/META-INF/MANIFEST.MF @@ -42,11 +42,11 @@ Export-Package: org.eclipse.cdt.core, org.eclipse.cdt.internal.core;x-friends:="org.eclipse.cdt.ui", org.eclipse.cdt.internal.core.browser.util;x-friends:="org.eclipse.cdt.ui", org.eclipse.cdt.internal.core.cdtvariables;x-internal:=true, - org.eclipse.cdt.internal.core.dom;x-friends:="org.eclipse.cdt.ui,org.eclipse.cdt.refactoring", - org.eclipse.cdt.internal.core.dom.parser;x-friends:="org.eclipse.cdt.refactoring", - org.eclipse.cdt.internal.core.dom.parser.c;x-friends:="org.eclipse.cdt.refactoring", - org.eclipse.cdt.internal.core.dom.parser.cpp;x-friends:="org.eclipse.cdt.ui,org.eclipse.cdt.refactoring", - org.eclipse.cdt.internal.core.dom.rewrite;x-friends:="org.eclipse.cdt.core.tests", + org.eclipse.cdt.internal.core.dom;x-friends:="org.eclipse.cdt.ui", + org.eclipse.cdt.internal.core.dom.parser;x-friends:="org.eclipse.cdt.ui", + org.eclipse.cdt.internal.core.dom.parser.c;x-friends:="org.eclipse.cdt.ui", + org.eclipse.cdt.internal.core.dom.parser.cpp;x-friends:="org.eclipse.cdt.ui", + org.eclipse.cdt.internal.core.dom.rewrite;x-friends:="org.eclipse.cdt.core.tests,org.eclipse.cdt.ui", org.eclipse.cdt.internal.core.dom.rewrite.astwriter;x-internal:=true, org.eclipse.cdt.internal.core.dom.rewrite.changegenerator;x-internal:=true, org.eclipse.cdt.internal.core.dom.rewrite.commenthandler;x-internal:=true, @@ -54,7 +54,7 @@ Export-Package: org.eclipse.cdt.core, org.eclipse.cdt.internal.core.index;x-friends:="org.eclipse.cdt.ui", org.eclipse.cdt.internal.core.index.provider;x-internal:=true, org.eclipse.cdt.internal.core.language;x-friends:="org.eclipse.cdt.ui", - org.eclipse.cdt.internal.core.model;x-friends:="org.eclipse.cdt.ui,org.eclipse.cdt.refactoring", + org.eclipse.cdt.internal.core.model;x-friends:="org.eclipse.cdt.ui", org.eclipse.cdt.internal.core.model.ext;x-friends:="org.eclipse.cdt.ui", org.eclipse.cdt.internal.core.parser;x-internal:=true, org.eclipse.cdt.internal.core.parser.problem;x-internal:=true, @@ -72,7 +72,7 @@ Export-Package: org.eclipse.cdt.core, org.eclipse.cdt.internal.errorparsers;x-internal:=true, org.eclipse.cdt.internal.formatter;x-internal:=true, org.eclipse.cdt.internal.formatter.align;x-internal:=true, - org.eclipse.cdt.internal.formatter.scanner;x-internal:=true, + org.eclipse.cdt.internal.formatter.scanner;x-friends:="org.eclipse.cdt.ui", org.eclipse.cdt.utils, org.eclipse.cdt.utils.cdtvariables, org.eclipse.cdt.utils.coff, diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/ASTRewriteAnalyzer.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/ASTRewriteAnalyzer.java index b86f09b6a9d..2b273d457ee 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/ASTRewriteAnalyzer.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/ASTRewriteAnalyzer.java @@ -12,13 +12,27 @@ package org.eclipse.cdt.internal.core.dom.rewrite; import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit; import org.eclipse.cdt.internal.core.dom.rewrite.changegenerator.ChangeGenerator; +import org.eclipse.core.resources.IFile; import org.eclipse.ltk.core.refactoring.Change; +import org.eclipse.ltk.core.refactoring.TextFileChange; public class ASTRewriteAnalyzer { + private static ICTextFileChangeFactory sFileChangeFactory; public static Change rewriteAST(IASTTranslationUnit root, ASTModificationStore modificationStore) { ChangeGenerator rewriter = new ChangeGenerator(modificationStore); rewriter.generateChange(root); return rewriter.getChange(); } + + public static void setCTextFileChangeFactory(ICTextFileChangeFactory factory) { + sFileChangeFactory= factory; + } + + public static TextFileChange createCTextFileChange(IFile file) { + if (sFileChangeFactory == null) { + return new TextFileChange(file.getName(), file); + } + return sFileChangeFactory.createCTextFileChange(file); + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/ICTextFileChangeFactory.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/ICTextFileChangeFactory.java new file mode 100644 index 00000000000..c544af7cc8a --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/ICTextFileChangeFactory.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * Copyright (c) 2008 Wind River Systems, Inc. and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Markus Schorn - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.core.dom.rewrite; + +import org.eclipse.core.resources.IFile; +import org.eclipse.ltk.core.refactoring.TextFileChange; + +/** + * Factory to create CTextFileChanges. Allows for creating ui-dependent objects in the core plugin. + * @since 5.0 + */ +public interface ICTextFileChangeFactory { + + /** + * Creates a text file change for the given file. + */ + TextFileChange createCTextFileChange(IFile file); +} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/changegenerator/CTextFileChange.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/changegenerator/CTextFileChange.java deleted file mode 100644 index 1c4cf31bb4d..00000000000 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/changegenerator/CTextFileChange.java +++ /dev/null @@ -1,223 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2008 Institute for Software, HSR Hochschule fuer Technik - * Rapperswil, University of applied sciences and others - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Institute for Software - initial API and implementation - *******************************************************************************/ -package org.eclipse.cdt.internal.core.dom.rewrite.changegenerator; - -import java.util.List; - -import org.eclipse.core.resources.IFile; -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.jface.text.IDocument; -import org.eclipse.jface.text.IRegion; -import org.eclipse.ltk.core.refactoring.Change; -import org.eclipse.ltk.core.refactoring.ChangeDescriptor; -import org.eclipse.ltk.core.refactoring.RefactoringStatus; -import org.eclipse.ltk.core.refactoring.TextEditBasedChangeGroup; -import org.eclipse.ltk.core.refactoring.TextEditChangeGroup; -import org.eclipse.ltk.core.refactoring.TextFileChange; -import org.eclipse.text.edits.MalformedTreeException; -import org.eclipse.text.edits.TextEdit; -import org.eclipse.text.edits.TextEditGroup; - -/** - * @author Emanuel Graf - * - */ -public class CTextFileChange extends Change { - - private TextFileChange change; - - /** - * @param name - * @param file - */ - public CTextFileChange(String name, IFile file) { - change = new TextFileChange(name, file); - } - - @Override - public Object getModifiedElement() { - return change.getModifiedElement(); - } - - @Override - public String getName() { - return change.getName(); - } - - @Override - public void initializeValidationData(IProgressMonitor pm) { - change.initializeValidationData(pm); - } - - @Override - public Change perform(IProgressMonitor pm) throws CoreException { - return change.perform(pm); - } - - public void setEdit(TextEdit edit) { - change.setEdit(edit); - } - - public TextEdit getEdit() { - return change.getEdit(); - } - - public void addTextEditGroup(TextEditBasedChangeGroup group) { - change.addChangeGroup(group); - } - - public String getCurrentContent(IProgressMonitor pm) throws CoreException{ - return change.getCurrentContent(pm); - } - - public String getPreviewContent(IProgressMonitor pm) throws CoreException{ - return change.getPreviewContent(pm); - } - public String getTextType() { - return change.getTextType(); - } - - public IFile getFile() { - return change.getFile(); - } - - public void addChangeGroup(TextEditBasedChangeGroup group) { - change.addChangeGroup(group); - } - - public void addEdit(TextEdit edit) throws MalformedTreeException { - change.addEdit(edit); - } - - public void addTextEditChangeGroup(TextEditChangeGroup group) { - change.addTextEditChangeGroup(group); - } - - public void addTextEditGroup(TextEditGroup group) { - change.addTextEditGroup(group); - } - - @Override - public void dispose() { - change.dispose(); - } - - @Override - public boolean equals(Object obj) { - return change.equals(obj); - } - - @Override - @SuppressWarnings("unchecked") - public Object getAdapter(Class adapter) { - return change.getAdapter(adapter); - } - - @Override - public Object[] getAffectedObjects() { - return change.getAffectedObjects(); - } - - public String getCurrentContent(IRegion region, boolean expandRegionToFullLine, int surroundingLines, IProgressMonitor pm) throws CoreException { - return change.getCurrentContent(region, expandRegionToFullLine, surroundingLines, pm); - } - - public IDocument getCurrentDocument(IProgressMonitor pm) throws CoreException { - return change.getCurrentDocument(pm); - } - - @Override - public ChangeDescriptor getDescriptor() { - return change.getDescriptor(); - } - - public boolean getKeepPreviewEdits() { - return change.getKeepPreviewEdits(); - } - - @Override - public Change getParent() { - return change.getParent(); - } - - public String getPreviewContent(TextEditBasedChangeGroup[] changeGroups, IRegion region, boolean expandRegionToFullLine, int surroundingLines, IProgressMonitor pm) throws CoreException { - return change.getPreviewContent(changeGroups, region, expandRegionToFullLine, surroundingLines, pm); - } - - public String getPreviewContent(TextEditChangeGroup[] changeGroups, IRegion region, boolean expandRegionToFullLine, int surroundingLines, IProgressMonitor pm) throws CoreException { - return change.getPreviewContent(changeGroups, region, expandRegionToFullLine, surroundingLines, pm); - } - - public IDocument getPreviewDocument(IProgressMonitor pm) throws CoreException { - return change.getPreviewDocument(pm); - } - - public TextEdit getPreviewEdit(TextEdit original) { - return change.getPreviewEdit(original); - } - - public TextEdit[] getPreviewEdits(TextEdit[] originals) { - return change.getPreviewEdits(originals); - } - - public int getSaveMode() { - return change.getSaveMode(); - } - - public TextEditChangeGroup[] getTextEditChangeGroups() { - return change.getTextEditChangeGroups(); - } - - @Override - public int hashCode() { - return change.hashCode(); - } - - @SuppressWarnings("unchecked") - public boolean hasOneGroupCategory(List groupCategories) { - return change.hasOneGroupCategory(groupCategories); - } - - @Override - public boolean isEnabled() { - return change.isEnabled(); - } - - @Override - public RefactoringStatus isValid(IProgressMonitor pm) throws CoreException { - return change.isValid(pm); - } - - @Override - public void setEnabled(boolean enabled) { - change.setEnabled(enabled); - } - - public void setKeepPreviewEdits(boolean keep) { - change.setKeepPreviewEdits(keep); - } - - public void setSaveMode(int saveMode) { - change.setSaveMode(saveMode); - } - - public void setTextType(String type) { - change.setTextType(type); - } - - @Override - public String toString() { - return change.toString(); - } - -} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/changegenerator/ChangeGenerator.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/changegenerator/ChangeGenerator.java index c792011b218..231733a9ee7 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/changegenerator/ChangeGenerator.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/changegenerator/ChangeGenerator.java @@ -30,6 +30,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.CPPASTVisitor; import org.eclipse.cdt.internal.core.dom.rewrite.ASTModification; import org.eclipse.cdt.internal.core.dom.rewrite.ASTModificationMap; import org.eclipse.cdt.internal.core.dom.rewrite.ASTModificationStore; +import org.eclipse.cdt.internal.core.dom.rewrite.ASTRewriteAnalyzer; import org.eclipse.cdt.internal.core.dom.rewrite.astwriter.ASTWriter; import org.eclipse.cdt.internal.core.dom.rewrite.astwriter.ProblemRuntimeException; import org.eclipse.cdt.internal.core.dom.rewrite.util.FileContentHelper; @@ -40,6 +41,7 @@ import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.Path; import org.eclipse.ltk.core.refactoring.Change; import org.eclipse.ltk.core.refactoring.CompositeChange; +import org.eclipse.ltk.core.refactoring.TextFileChange; import org.eclipse.text.edits.DeleteEdit; import org.eclipse.text.edits.InsertEdit; import org.eclipse.text.edits.MultiTextEdit; @@ -98,8 +100,7 @@ public class ChangeGenerator extends CPPASTVisitor { rootNode.accept(pathProvider); for (IFile currentFile : changes.keySet()) { - CTextFileChange subchange = new CTextFileChange(currentFile - .getName(), currentFile); + TextFileChange subchange= ASTRewriteAnalyzer.createCTextFileChange(currentFile); subchange.setEdit(changes.get(currentFile)); change.add(subchange); } diff --git a/core/org.eclipse.cdt.ui.tests/.classpath b/core/org.eclipse.cdt.ui.tests/.classpath index b0a17ea7314..e2fea57c451 100644 --- a/core/org.eclipse.cdt.ui.tests/.classpath +++ b/core/org.eclipse.cdt.ui.tests/.classpath @@ -2,7 +2,7 @@ - + diff --git a/core/org.eclipse.cdt.ui.tests/.settings/org.eclipse.jdt.core.prefs b/core/org.eclipse.cdt.ui.tests/.settings/org.eclipse.jdt.core.prefs index f9b0a2ca0a4..684bece864b 100644 --- a/core/org.eclipse.cdt.ui.tests/.settings/org.eclipse.jdt.core.prefs +++ b/core/org.eclipse.cdt.ui.tests/.settings/org.eclipse.jdt.core.prefs @@ -1,9 +1,9 @@ -#Fri Feb 15 10:15:35 CET 2008 +#Wed Feb 27 13:20:15 CET 2008 eclipse.preferences.version=1 org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=disabled -org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.4 +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5 org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve -org.eclipse.jdt.core.compiler.compliance=1.4 +org.eclipse.jdt.core.compiler.compliance=1.5 org.eclipse.jdt.core.compiler.debug.lineNumber=generate org.eclipse.jdt.core.compiler.debug.localVariable=generate org.eclipse.jdt.core.compiler.debug.sourceFile=generate @@ -16,7 +16,7 @@ org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=disabled org.eclipse.jdt.core.compiler.problem.discouragedReference=ignore org.eclipse.jdt.core.compiler.problem.emptyStatement=ignore -org.eclipse.jdt.core.compiler.problem.enumIdentifier=warning +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error org.eclipse.jdt.core.compiler.problem.fallthroughCase=warning org.eclipse.jdt.core.compiler.problem.fatalOptionalError=enabled org.eclipse.jdt.core.compiler.problem.fieldHiding=ignore @@ -79,7 +79,7 @@ org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disa org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=ignore org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning -org.eclipse.jdt.core.compiler.source=1.4 +org.eclipse.jdt.core.compiler.source=1.5 org.eclipse.jdt.core.formatter.align_type_members_on_columns=false org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16 org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant=16 @@ -151,7 +151,6 @@ org.eclipse.jdt.core.formatter.indent_statements_compare_to_body=true org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases=true org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch=false org.eclipse.jdt.core.formatter.indentation.size=4 -org.eclipse.jdt.core.formatter.insert_new_line_after_annotation=insert org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer=do not insert org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing=do not insert org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement=do not insert diff --git a/core/org.eclipse.cdt.ui.tests/META-INF/MANIFEST.MF b/core/org.eclipse.cdt.ui.tests/META-INF/MANIFEST.MF index e577675c810..0ae4b96ec9f 100644 --- a/core/org.eclipse.cdt.ui.tests/META-INF/MANIFEST.MF +++ b/core/org.eclipse.cdt.ui.tests/META-INF/MANIFEST.MF @@ -10,6 +10,7 @@ Export-Package: org.eclipse.cdt.ui.testplugin, org.eclipse.cdt.ui.tests, org.eclipse.cdt.ui.tests.DOMAST, org.eclipse.cdt.ui.tests.chelp, + org.eclipse.cdt.ui.tests.refactoring.rename, org.eclipse.cdt.ui.tests.text, org.eclipse.cdt.ui.tests.text.contentassist, org.eclipse.cdt.ui.tests.text.selection @@ -33,7 +34,7 @@ Require-Bundle: org.eclipse.jface.text, org.eclipse.core.expressions, org.eclipse.cdt.make.core, com.ibm.icu, - org.eclipse.cdt.refactoring.tests + org.eclipse.ltk.core.refactoring;bundle-version="3.4.0" Bundle-ActivationPolicy: lazy Bundle-Vendor: Eclipse.org -Bundle-RequiredExecutionEnvironment: J2SE-1.4 +Bundle-RequiredExecutionEnvironment: J2SE-1.5 diff --git a/core/org.eclipse.cdt.ui.tests/plugin.xml b/core/org.eclipse.cdt.ui.tests/plugin.xml index 72140c1c76f..8a98421c5b1 100644 --- a/core/org.eclipse.cdt.ui.tests/plugin.xml +++ b/core/org.eclipse.cdt.ui.tests/plugin.xml @@ -198,4 +198,21 @@ + + + + + + + + + + + + + + diff --git a/core/org.eclipse.cdt.ui.tests/resources/refactoring/ExtractConstant.rts b/core/org.eclipse.cdt.ui.tests/resources/refactoring/ExtractConstant.rts new file mode 100644 index 00000000000..e1a000aa607 --- /dev/null +++ b/core/org.eclipse.cdt.ui.tests/resources/refactoring/ExtractConstant.rts @@ -0,0 +1,370 @@ +//!ExtractConstantInt +//#org.eclipse.cdt.ui.tests.refactoring.extractconstant.ExtractConstantRefactoringTest +//@A.h +#ifndef A_H_ +#define A_H_ + +class A +{ +public: + A(); + virtual ~A(); + int foo(); + void bar(); +}; + +#endif /*A_H_*/ + + +//= +#ifndef A_H_ +#define A_H_ + +class A +{ +public: + A(); + virtual ~A(); + int foo(); + void bar(); + static const int theAnswer = 42; +}; + +#endif /*A_H_*/ + + +//@A.cpp +#include "A.h" + +A::A() +{ +} + +A::~A() +{ +} + +int A::foo() +{ + return //$42$//; +} + +void A::bar() +{ + int a = 42; + int b = 42; +} + +//= +#include "A.h" + +A::A() +{ +} + +A::~A() +{ +} + +int A::foo() +{ + return theAnswer; +} + +void A::bar() +{ + int a = theAnswer; + int b = theAnswer; +} + +//!ExtractConstantFloat +//#org.eclipse.cdt.ui.tests.refactoring.extractconstant.ExtractConstantRefactoringTest +//@A.h +#ifndef A_H_ +#define A_H_ + +class A +{ +public: + A(); + virtual ~A(); + float foo(); + void bar(); +}; + +#endif /*A_H_*/ + + +//= +#ifndef A_H_ +#define A_H_ + +class A +{ +public: + A(); + virtual ~A(); + float foo(); + void bar(); + static const float theAnswer = 42.0; +}; + +#endif /*A_H_*/ + + +//@A.cpp +#include "A.h" + +A::A() +{ +} + +A::~A() +{ +} + +float A::foo() +{ + return //$42.0$//; +} + +void A::bar() +{ + float a = 42.0; + float b = 42.0; +} + +//= +#include "A.h" + +A::A() +{ +} + +A::~A() +{ +} + +float A::foo() +{ + return theAnswer; +} + +void A::bar() +{ + float a = theAnswer; + float b = theAnswer; +} + +//!ExtractConstantStaticInt +//#org.eclipse.cdt.ui.tests.refactoring.extractconstant.ExtractConstantRefactoringTest +//@A.h +#ifndef A_H_ +#define A_H_ + +class A +{ +public: + A(); + virtual ~A(); + int foo(); + static const int a = 42; +}; + +#endif /*A_H_*/ + +//= +#ifndef A_H_ +#define A_H_ + +class A +{ +public: + A(); + virtual ~A(); + int foo(); + static const int a = 42; +}; + +#endif /*A_H_*/ + +//@A.cpp +#include "A.h" + +A::A() +{ +} + +A::~A() +{ +} + +int A::foo() +{ + return 42; +} + +int bar() +{ + return //$42$//; +} + + +//= +#include "A.h" + +namespace +{ + const int theAnswer = 42; +} +A::A() +{ +} + +A::~A() +{ +} + +int A::foo() +{ + return theAnswer; +} + +int bar() +{ + return theAnswer; +} + + +//!replaceNumberProtected +//#org.eclipse.cdt.ui.tests.refactoring.extractconstant.ExtractConstantRefactoringTest +//@.config +visibility=protected +//@A.h +#ifndef A_H_ +#define A_H_ + +class A +{ +public: + A(); + virtual ~A(); + int foo(); +}; + +#endif /*A_H_*/ + +//= +#ifndef A_H_ +#define A_H_ + +class A +{ +public: + A(); + virtual ~A(); + int foo(); +protected: + static const int theAnswer = 42; +}; + +#endif /*A_H_*/ + +//@A.cpp +#include "A.h" + +A::A() +{ +} + +A::~A() +{ +} + +int A::foo() +{ + return //$42$//; +} + +//= +#include "A.h" + +A::A() +{ +} + +A::~A() +{ +} + +int A::foo() +{ + return theAnswer; +} + +//!replaceNumberPrivate +//#org.eclipse.cdt.ui.tests.refactoring.extractconstant.ExtractConstantRefactoringTest +//@.config +visibility=private +//@A.h +#ifndef A_H_ +#define A_H_ + +class A +{ +public: + A(); + virtual ~A(); + int foo(); +}; + +#endif /*A_H_*/ + +//= +#ifndef A_H_ +#define A_H_ + +class A +{ +public: + A(); + virtual ~A(); + int foo(); +private: + static const int theAnswer = 42; +}; + +#endif /*A_H_*/ + +//@A.cpp +#include "A.h" + +A::A() +{ +} + +A::~A() +{ +} + +int A::foo() +{ + return //$42$//; +} + +//= +#include "A.h" + +A::A() +{ +} + +A::~A() +{ +} + +int A::foo() +{ + return theAnswer; +} + diff --git a/core/org.eclipse.cdt.ui.tests/resources/refactoring/TranslationunitHelper.rts b/core/org.eclipse.cdt.ui.tests/resources/refactoring/TranslationunitHelper.rts new file mode 100644 index 00000000000..a277b9e4566 --- /dev/null +++ b/core/org.eclipse.cdt.ui.tests/resources/refactoring/TranslationunitHelper.rts @@ -0,0 +1,35 @@ +//!before the class +//#org.eclipse.cdt.ui.tests.refactoring.utils.TranslationUnitHelperTest +//@.config +filename=A.h +offset_unix=27 +offset_win=30 +//@A.h +#ifndef A_H_ +#define A_H_ + +class A +{ +public: + A(); + void foo(); +}; + +#endif /*A_H_*/ + + +//!before a typedef +//#org.eclipse.cdt.ui.tests.refactoring.utils.TranslationUnitHelperTest +//@.config +filename=A.h +offset_unix=0 +offset_win=0 +//@A.h +typedef int nummere; + +class A +{ +public: + A(); +}; + diff --git a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/AutomatedSuite.java b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/AutomatedSuite.java index 892c9f4b79e..98da9377358 100644 --- a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/AutomatedSuite.java +++ b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/AutomatedSuite.java @@ -15,10 +15,10 @@ package org.eclipse.cdt.ui.tests; import junit.framework.Test; import junit.framework.TestSuite; -import org.eclipse.cdt.refactoring.tests.RenameRegressionTests; import org.eclipse.cdt.ui.tests.buildconsole.BuildConsoleTests; import org.eclipse.cdt.ui.tests.callhierarchy.CallHierarchyTestSuite; import org.eclipse.cdt.ui.tests.includebrowser.IncludeBrowserTestSuite; +import org.eclipse.cdt.ui.tests.refactoring.RefactoringTestSuite; import org.eclipse.cdt.ui.tests.search.SearchTestSuite; import org.eclipse.cdt.ui.tests.text.TextTestSuite; import org.eclipse.cdt.ui.tests.text.contentassist.ContentAssistTestSuite; @@ -36,14 +36,14 @@ public class AutomatedSuite extends TestSuite { * Returns the suite. This is required to * use the JUnit Launcher. */ - public static Test suite() { + public static Test suite() throws Exception { return new AutomatedSuite(); } /** * Construct the test suite. */ - public AutomatedSuite() { + public AutomatedSuite() throws Exception { // tests from package org.eclipse.cdt.ui.tests.text addTest(TextTestSuite.suite()); @@ -65,9 +65,6 @@ public class AutomatedSuite extends TestSuite { // tests from package org.eclipse.cdt.ui.tests.text.contentAssist2 addTest(ContentAssist2TestSuite.suite()); - - // tests from the refactoring plugin - addTest(RenameRegressionTests.suite()); // tests from package org.eclipse.cdt.ui.tests.text.selection addTest(SelectionTestSuite.suite()); @@ -77,6 +74,9 @@ public class AutomatedSuite extends TestSuite { // tests from package org.eclipse.cdt.ui.tests.search addTest(SearchTestSuite.suite()); + + // tests from package org.eclipse.cdt.ui.tests.refactoring + addTest(RefactoringTestSuite.suite()); } } diff --git a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/refactoring/Messages.java b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/refactoring/Messages.java new file mode 100644 index 00000000000..85863e7c112 --- /dev/null +++ b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/refactoring/Messages.java @@ -0,0 +1,33 @@ +/******************************************************************************* + * Copyright (c) 2008 Institute for Software, HSR Hochschule fuer Technik + * Rapperswil, University of applied sciences and others + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Institute for Software - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.ui.tests.refactoring; + +import java.util.MissingResourceException; +import java.util.ResourceBundle; + +public class Messages { + private static final String BUNDLE_NAME = "org.eclipse.cdt.ui.tests.refactoring.messages"; //$NON-NLS-1$ + + private static final ResourceBundle RESOURCE_BUNDLE = ResourceBundle + .getBundle(BUNDLE_NAME); + + private Messages() { + } + + public static String getString(String key) { + try { + return RESOURCE_BUNDLE.getString(key); + } catch (MissingResourceException e) { + return '!' + key + '!'; + } + } +} diff --git a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/refactoring/RefactoringBaseTest.java b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/refactoring/RefactoringBaseTest.java new file mode 100644 index 00000000000..f705bc44d3c --- /dev/null +++ b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/refactoring/RefactoringBaseTest.java @@ -0,0 +1,116 @@ +/******************************************************************************* + * Copyright (c) 2008 Institute for Software, HSR Hochschule fuer Technik + * Rapperswil, University of applied sciences and others + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Institute for Software - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.ui.tests.refactoring; + +import java.io.BufferedReader; +import java.io.InputStreamReader; +import java.util.Map; +import java.util.TreeMap; +import java.util.Vector; + +import org.eclipse.cdt.core.tests.BaseTestFramework; +import org.eclipse.core.resources.IFile; +import org.eclipse.core.runtime.ILogListener; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.NullProgressMonitor; +import org.eclipse.core.runtime.Path; +import org.eclipse.jface.text.TextSelection; + +/** + * @author Guido Zgraggen IFS + * + */ +public abstract class RefactoringBaseTest extends BaseTestFramework implements ILogListener{ + protected static final NullProgressMonitor NULL_PROGRESS_MONITOR = new NullProgressMonitor(); + + protected TreeMap fileMap = new TreeMap(); + protected String fileWithSelection; + protected TextSelection selection; + + protected RefactoringBaseTest(String name) { + super(name); + } + + public RefactoringBaseTest(String name, Vector files) { + super(name); + for (TestSourceFile file : files) { + fileMap.put(file.getName(), file); + } + } + + @Override + protected abstract void runTest() throws Throwable; + + + @Override + protected void setUp() throws Exception { + super.setUp(); + for (TestSourceFile testFile : fileMap.values()) { + if(testFile.getSource().length() > 0) { + importFile(testFile.getName(), testFile.getSource()); + } + } + } + + protected void assertEquals(TestSourceFile file, IFile file2) throws Exception { + StringBuffer code = getCodeFromIFile(file2); + assertEquals(file.getExpectedSource(), TestHelper.unifyNewLines(code.toString())); + } + + protected void compareFiles(Map testResourceFiles) throws Exception { + for (String fileName : testResourceFiles.keySet()) { + TestSourceFile file = testResourceFiles.get(fileName); + IFile iFile = project.getFile(new Path(fileName)); + StringBuffer code = getCodeFromIFile(iFile); + assertEquals(TestHelper.unifyNewLines(file.getExpectedSource()), TestHelper.unifyNewLines(code.toString())); + } + } + + protected StringBuffer getCodeFromIFile(IFile file) throws Exception { + BufferedReader br = new BufferedReader(new InputStreamReader(file.getContents())); + StringBuffer code = new StringBuffer(); + String line; + while((line = br.readLine()) != null) { + code.append(line); + code.append('\n'); + } + br.close(); + return code; + } + + @Override + protected void tearDown() throws Exception { + System.gc(); + fileManager.closeAllFiles(); + super.tearDown(); + } + + public void logging(IStatus status, String plugin) { + Throwable ex = status.getException(); + StringBuffer stackTrace = new StringBuffer(); + if(ex != null) { + stackTrace.append('\n'); + for(StackTraceElement ste : ex.getStackTrace()) { + stackTrace.append(ste.toString()); + } + } + fail("Log-Message: " + status.getMessage() + stackTrace.toString()); //$NON-NLS-1$ + } + + public void setFileWithSelection(String fileWithSelection) { + this.fileWithSelection = fileWithSelection; + } + + public void setSelection(TextSelection selection) { + this.selection = selection; + } +} diff --git a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/refactoring/RefactoringTest.java b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/refactoring/RefactoringTest.java new file mode 100644 index 00000000000..7523d81fc19 --- /dev/null +++ b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/refactoring/RefactoringTest.java @@ -0,0 +1,150 @@ +/******************************************************************************* + * Copyright (c) 2008 Institute for Software, HSR Hochschule fuer Technik + * Rapperswil, University of applied sciences and others + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Institute for Software - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.ui.tests.refactoring; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.util.Properties; +import java.util.Vector; + +import org.eclipse.ltk.core.refactoring.RefactoringStatus; +import org.eclipse.ltk.core.refactoring.RefactoringStatusEntry; + +import org.eclipse.cdt.core.CCorePlugin; +import org.eclipse.cdt.core.dom.IPDOMManager; +import org.eclipse.cdt.core.index.IIndexManager; +import org.eclipse.cdt.ui.testplugin.CTestPlugin; + +/** + * @author Emanuel Graf + * + */ +public abstract class RefactoringTest extends RefactoringBaseTest { + + private static final String CONFIG_FILE_NAME = ".config"; //$NON-NLS-1$ + + protected String fileName; + + public RefactoringTest(String name, Vector files) { + super(name, files); + initializeConfiguration(files); + for (TestSourceFile file : files) { + fileMap.put(file.getName(), file); + } + } + + protected abstract void configureRefactoring(Properties refactoringProperties); + + @Override + protected void setUp() throws Exception { + super.setUp(); + CCorePlugin.getIndexManager().setIndexerId(cproject, IPDOMManager.ID_FAST_INDEXER); + CTestPlugin.getDefault().getLog().addLogListener(this); + CCorePlugin.getIndexManager().reindex(cproject); + boolean joined = CCorePlugin.getIndexManager().joinIndexer(IIndexManager.FOREVER, NULL_PROGRESS_MONITOR); + assertTrue(joined); + } + + private void initializeConfiguration(Vector files) { + TestSourceFile configFile = null; + + for (TestSourceFile currentFile : files) { + if (currentFile.getName().equals(CONFIG_FILE_NAME)) { + configFile = currentFile; + } + } + + Properties refactoringProperties = new Properties(); + + try { + if(configFile != null) { + refactoringProperties.load(new ByteArrayInputStream(configFile.getSource().getBytes())); + } + } catch (IOException e) { + // Property initialization failed + } + + initCommonFields(refactoringProperties); + configureRefactoring(refactoringProperties); + files.remove(configFile); + + } + + private void initCommonFields(Properties refactoringProperties) { + fileName = refactoringProperties.getProperty("filename", "A.cpp"); //$NON-NLS-1$ //$NON-NLS-2$ + } + + protected void assertConditionsOk(RefactoringStatus conditions) { + assertTrue(conditions.isOK() ? "OK" : "Error or Warning in initial Conditions: " + conditions.getEntries()[0].getMessage() //$NON-NLS-1$ //$NON-NLS-2$ + , conditions.isOK()); + } + + protected void assertConditionsWarning(RefactoringStatus conditions, int number) { + if (number > 0) { + assertTrue("Warning in Condition expected", conditions.hasWarning()); //$NON-NLS-1$ + } + RefactoringStatusEntry[] entries = conditions.getEntries(); + int count = 0; + for (RefactoringStatusEntry entry : entries) { + if (entry.isWarning()) { + ++count; + } + } + assertEquals(number + " Warnings expected found " + count, count, number); //$NON-NLS-1$ + } + + protected void assertConditionsInfo(RefactoringStatus status, int number) { + if (number > 0) { + assertTrue("Info in Condition expected", status.hasInfo()); //$NON-NLS-1$ + } + RefactoringStatusEntry[] entries = status.getEntries(); + int count = 0; + for (RefactoringStatusEntry entry : entries) { + if (entry.isInfo()) { + ++count; + } + } + assertEquals(number + " Infos expected found " + count, number, count); //$NON-NLS-1$ + } + + protected void assertConditionsError(RefactoringStatus status, int number) { + if (number > 0) { + assertTrue("Error in Condition expected", status.hasError()); //$NON-NLS-1$ + } + RefactoringStatusEntry[] entries = status.getEntries(); + int count = 0; + for (RefactoringStatusEntry entry : entries) { + if (entry.isError()) { + ++count; + } + } + assertEquals(number + " Errors expected found " + count, number, count); //$NON-NLS-1$ + } + + protected void assertConditionsFatalError(RefactoringStatus status, int number) { + if (number > 0) { + assertTrue("Fatal Error in Condition expected", status.hasFatalError()); //$NON-NLS-1$ + } + RefactoringStatusEntry[] entries = status.getEntries(); + int count = 0; + for (RefactoringStatusEntry entry : entries) { + if (entry.isFatalError()) { + ++count; + } + } + assertEquals(number + " Fatal Errors expected found " + count, number, count); //$NON-NLS-1$ + } + + protected void assertConditionsFatalError(RefactoringStatus conditions) { + assertTrue("Fatal Error in Condition expected", conditions.hasFatalError()); //$NON-NLS-1$ + } +} diff --git a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/refactoring/RefactoringTestSuite.java b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/refactoring/RefactoringTestSuite.java new file mode 100644 index 00000000000..7a3fbf47520 --- /dev/null +++ b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/refactoring/RefactoringTestSuite.java @@ -0,0 +1,34 @@ +/******************************************************************************* + * Copyright (c) 2008 Institute for Software, HSR Hochschule fuer Technik + * Rapperswil, University of applied sciences and others + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Institute for Software - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.ui.tests.refactoring; + +import junit.framework.Test; +import junit.framework.TestSuite; + +import org.eclipse.cdt.ui.tests.refactoring.rename.RenameRegressionTests; +import org.eclipse.cdt.ui.tests.refactoring.utils.UtilTestSuite; + +/** + * @author Emanuel Graf + * + */ +public class RefactoringTestSuite extends TestSuite { + + public static Test suite() throws Exception { + TestSuite suite = new RefactoringTestSuite(); + suite.addTest(RenameRegressionTests.suite()); + suite.addTest(RefactoringTester.suite("ExtractConstantRefactoringTests", "resources/refactoring/ExtractConstant.rts")); + suite.addTest(UtilTestSuite.suite()); + return suite; + } + +} diff --git a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/refactoring/RefactoringTester.java b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/refactoring/RefactoringTester.java new file mode 100644 index 00000000000..203a704bc00 --- /dev/null +++ b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/refactoring/RefactoringTester.java @@ -0,0 +1,216 @@ +/******************************************************************************* + * Copyright (c) 2008 Institute for Software, HSR Hochschule fuer Technik + * Rapperswil, University of applied sciences and others + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Institute for Software - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.ui.tests.refactoring; + +import java.io.BufferedReader; +import java.io.FileReader; +import java.io.IOException; +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.Vector; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import junit.framework.Test; +import junit.framework.TestSuite; + +import org.eclipse.core.runtime.FileLocator; +import org.eclipse.core.runtime.Path; +import org.eclipse.jface.text.TextSelection; +import org.osgi.framework.Bundle; + +import org.eclipse.cdt.ui.testplugin.CTestPlugin; + +/** + * @author Emanuel Graf + * + */ +public class RefactoringTester extends TestSuite{ + + enum MatcherState{skip, inTest, inSource, inExpectedResult} + + private static final String classRegexp = "//#(.*)\\s*(\\w*)*$"; //$NON-NLS-1$ + private static final String testRegexp = "//!(.*)\\s*(\\w*)*$"; //$NON-NLS-1$ + private static final String fileRegexp = "//@(.*)\\s*(\\w*)*$"; //$NON-NLS-1$ + private static final String resultRegexp = "//=.*$"; //$NON-NLS-1$ + + public static Test suite(String name, String file)throws Exception { + BufferedReader in = createReader(file); + + ArrayList testCases = createTests(in); + in.close(); + return createSuite(testCases, name); + } + + protected static BufferedReader createReader(String file) throws IOException { + Bundle bundle = CTestPlugin.getDefault().getBundle(); + Path path = new Path(file); + String file2 = FileLocator.toFileURL(FileLocator.find(bundle, path, null)).getFile(); + return new BufferedReader(new FileReader(file2)); + } + + private static ArrayList createTests(BufferedReader inputReader) throws Exception { + + String line; + Vector files = new Vector(); + TestSourceFile actFile = null; + MatcherState matcherState = MatcherState.skip; + ArrayList testCases = new ArrayList(); + String testName = null; + String className = null; + boolean bevorFirstTest = true; + + while ((line = inputReader.readLine()) != null){ + + if(lineMatchesBeginOfTest(line)) { + if(!bevorFirstTest) { + RefactoringBaseTest test = createTestClass(className, testName, files); + testCases.add(test); + files = new Vector(); + className = null; + testName = null; + } + matcherState = MatcherState.inTest; + testName = getNameOfTest(line); + bevorFirstTest = false; + continue; + } else if (lineMatchesBeginOfResult(line)) { + matcherState = MatcherState.inExpectedResult; + continue; + }else if (lineMatchesFileName(line)) { + matcherState = MatcherState.inSource; + actFile = new TestSourceFile(getFileName(line)); + files.add(actFile); + continue; + }else if(lineMatchesClassName(line)) { + className = getNameOfClass(line); + continue; + } + + switch(matcherState) { + case inSource: + if(actFile != null) { + actFile.addLineToSource(line); + } + break; + case inExpectedResult: + if(actFile != null) { + actFile.addLineToExpectedSource(line); + } + break; + default: + break; + } + } + RefactoringBaseTest test = createTestClass(className, testName, files); + testCases.add(test); + return testCases; + } + + + + private static RefactoringBaseTest createTestClass(String className, String testName, Vector files) throws Exception { + + + try { + Class refClass = Class.forName(className); + Class paratypes[] = new Class[2]; + paratypes[0] = testName.getClass(); + paratypes[1] = files.getClass(); + Constructor ct = refClass.getConstructor(paratypes); + Object arglist[] = new Object[2]; + arglist[0] = testName; + arglist[1] = files; + RefactoringBaseTest test = (RefactoringBaseTest) ct.newInstance(arglist); + for (TestSourceFile file : files) { + TextSelection sel = file.getSelection(); + if(sel != null) { + test.setFileWithSelection(file.getName()); + test.setSelection(sel); + break; + } + } + return test; + } catch (ClassNotFoundException e) { + throw new Exception(Messages.getString("RefactoringTester.UnknownTestClass")); //$NON-NLS-1$ + } catch (SecurityException e) { + throw new Exception(Messages.getString("RefactoringTester.SecurityException"), e); //$NON-NLS-1$ + } catch (NoSuchMethodException e) { + throw new Exception(Messages.getString("RefactoringTester.ConstructorError")); //$NON-NLS-1$ + } catch (IllegalArgumentException e) { + throw new Exception(Messages.getString("RefactoringTester.IllegalArgument"), e); //$NON-NLS-1$ + } catch (InstantiationException e) { + throw new Exception(Messages.getString("RefactoringTester.InstantiationException"), e); //$NON-NLS-1$ + } catch (IllegalAccessException e) { + throw new Exception(Messages.getString("RefactoringTester.IllegalAccessException"), e); //$NON-NLS-1$ + } catch (InvocationTargetException e) { + throw new Exception(Messages.getString("RefactoringTester.InvocationTargetException"), e); //$NON-NLS-1$ + } + } + + private static String getFileName(String line) { + Matcher matcherBeginOfTest = createMatcherFromString(fileRegexp, line); + if(matcherBeginOfTest.find()) + return matcherBeginOfTest.group(1); + else + return null; + } + + private static String getNameOfClass(String line) { + Matcher matcherBeginOfTest = createMatcherFromString(classRegexp, line); + if(matcherBeginOfTest.find()) + return matcherBeginOfTest.group(1); + else + return null; + } + + private static boolean lineMatchesBeginOfTest(String line) { + return createMatcherFromString(testRegexp, line).find(); + } + + private static boolean lineMatchesClassName(String line) { + return createMatcherFromString(classRegexp, line).find(); + } + + private static boolean lineMatchesFileName(String line) { + return createMatcherFromString(fileRegexp, line).find(); + } + + protected static Matcher createMatcherFromString(String pattern, String line) { + return Pattern.compile(pattern).matcher(line); + } + + private static String getNameOfTest(String line) { + Matcher matcherBeginOfTest = createMatcherFromString(testRegexp, line); + if(matcherBeginOfTest.find()) + return matcherBeginOfTest.group(1); + else + return Messages.getString("RefactoringTester.NotNamed"); //$NON-NLS-1$ + } + + private static boolean lineMatchesBeginOfResult(String line) { + return createMatcherFromString(resultRegexp, line).find(); + } + + private static TestSuite createSuite(ArrayList testCases, String name) { + TestSuite suite = new TestSuite(name); + Iterator it = testCases.iterator(); + while(it.hasNext()) { + RefactoringBaseTest subject =it.next(); + suite.addTest(subject); + } + return suite; + } +} + diff --git a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/refactoring/TestHelper.java b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/refactoring/TestHelper.java new file mode 100644 index 00000000000..a2ec884cede --- /dev/null +++ b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/refactoring/TestHelper.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright (c) 2008 Institute for Software, HSR Hochschule fuer Technik + * Rapperswil, University of applied sciences and others + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Institute for Software - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.ui.tests.refactoring; + +public class TestHelper { + + public static String unifyNewLines(String code) { + String replacement = System.getProperty("line.separator"); //$NON-NLS-1$ + return code.replaceAll("(\n)|(\r\n)", replacement); //$NON-NLS-1$ + } +} diff --git a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/refactoring/TestSourceFile.java b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/refactoring/TestSourceFile.java new file mode 100644 index 00000000000..04b5905e5cd --- /dev/null +++ b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/refactoring/TestSourceFile.java @@ -0,0 +1,88 @@ +/******************************************************************************* + * Copyright (c) 2008 Institute for Software, HSR Hochschule fuer Technik + * Rapperswil, University of applied sciences and others + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Institute for Software - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.ui.tests.refactoring; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import org.eclipse.jface.text.TextSelection; + +/** + * @author Emanuel Graf + * + */ +public class TestSourceFile { + + private static final String REPLACEMENT = ""; //$NON-NLS-1$ + private String name; + private StringBuffer source = new StringBuffer(); + private StringBuffer expectedSource = new StringBuffer(); + private String separator = System.getProperty("line.separator"); //$NON-NLS-1$ + private int selectionStart = -1; + private int selectionEnd = -1; + + protected static final String selectionStartRegex = "//\\$"; //$NON-NLS-1$ + protected static final String selectionEndRegex = "\\$//"; //$NON-NLS-1$ + protected static final String selectionStartLineRegex = "(.*)(" + selectionStartRegex + ")(.*)"; //$NON-NLS-1$ //$NON-NLS-2$ + protected static final String selectionEndLineRegex = "(.*)("+ selectionEndRegex + ")(.*)"; //$NON-NLS-1$ //$NON-NLS-2$ + + public TestSourceFile(String name) { + super(); + this.name = name; + } + public String getExpectedSource() { + String exp = expectedSource.toString(); + if(exp.length() == 0) { + return getSource(); + }else { + return exp; + } + } + public String getName() { + return name; + } + public String getSource() { + return source.toString(); + } + + public void addLineToSource(String code) { + Matcher start = createMatcherFromString(selectionStartLineRegex, code); + if(start.matches()) { + selectionStart = start.start(2) + source.length(); + code = code.replaceAll(selectionStartRegex, REPLACEMENT); + } + Matcher end = createMatcherFromString(selectionEndLineRegex, code); + if(end.matches()) { + selectionEnd = end.start(2) + source.length(); + code = code.replaceAll(selectionEndRegex, REPLACEMENT); + } + source.append(code); + source.append(separator); + } + + public void addLineToExpectedSource(String code) { + expectedSource.append(code); + expectedSource.append(separator); + } + + public TextSelection getSelection() { + if(selectionStart < 0 || selectionEnd <0 ) { + return null; + }else { + return new TextSelection(selectionStart, selectionEnd -selectionStart); + } + } + + protected static Matcher createMatcherFromString(String pattern, String line) { + return Pattern.compile(pattern).matcher(line); + } +} diff --git a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/refactoring/extractconstant/ExtractConstantRefactoringTest.java b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/refactoring/extractconstant/ExtractConstantRefactoringTest.java new file mode 100644 index 00000000000..3722ad107cc --- /dev/null +++ b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/refactoring/extractconstant/ExtractConstantRefactoringTest.java @@ -0,0 +1,64 @@ +/******************************************************************************* + * Copyright (c) 2008 Institute for Software, HSR Hochschule fuer Technik + * Rapperswil, University of applied sciences and others + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Institute for Software - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.ui.tests.refactoring.extractconstant; + +import java.util.Properties; +import java.util.Vector; + +import org.eclipse.core.resources.IFile; +import org.eclipse.ltk.core.refactoring.Change; +import org.eclipse.ltk.core.refactoring.RefactoringStatus; + +import org.eclipse.cdt.ui.tests.refactoring.RefactoringTest; +import org.eclipse.cdt.ui.tests.refactoring.TestSourceFile; + +import org.eclipse.cdt.internal.ui.refactoring.NameNVisibilityInformation; +import org.eclipse.cdt.internal.ui.refactoring.extractconstant.ExtractConstantRefactoring; +import org.eclipse.cdt.internal.ui.refactoring.utils.VisibilityEnum; + +/** + * @author Emanuel Graf + */ +public class ExtractConstantRefactoringTest extends RefactoringTest { + + + protected VisibilityEnum visibility; + + public ExtractConstantRefactoringTest(String name, Vector files) { + super(name, files); + } + + @Override + protected void runTest() throws Throwable { + IFile refFile = project.getFile(fileName); + NameNVisibilityInformation info = new NameNVisibilityInformation(); + ExtractConstantRefactoring refactoring = new ExtractConstantRefactoring( refFile, selection, info, true); + RefactoringStatus checkInitialConditions = refactoring.checkInitialConditions(NULL_PROGRESS_MONITOR); + assertConditionsOk(checkInitialConditions); + info.setName("theAnswer"); //$NON-NLS-1$ + info.setVisibility(visibility); + Change createChange = refactoring.createChange(NULL_PROGRESS_MONITOR); + RefactoringStatus finalConditions = refactoring.checkFinalConditions(NULL_PROGRESS_MONITOR); + assertConditionsOk(finalConditions); + createChange.perform(NULL_PROGRESS_MONITOR); + + compareFiles(fileMap); + + } + + @Override + protected void configureRefactoring(Properties refactoringProperties) { + visibility = VisibilityEnum.getEnumForStringRepresentation(refactoringProperties.getProperty("visibility", VisibilityEnum.v_public.toString())); //$NON-NLS-1$ + + } + +} diff --git a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/refactoring/messages.properties b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/refactoring/messages.properties new file mode 100644 index 00000000000..04890cb5ab7 --- /dev/null +++ b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/refactoring/messages.properties @@ -0,0 +1,8 @@ +RefactoringTester.UnknownTestClass=Unknown TestClass. Make sure the test's sourcefile specifies a valid test class. +RefactoringTester.SecurityException=Security Exception during Test creation +RefactoringTester.ConstructorError=Test class does not provied required constructor. +RefactoringTester.IllegalArgument=IllegalArgumentException during Test creation +RefactoringTester.InstantiationException=InstantiationException during Test creation +RefactoringTester.IllegalAccessException=IllegalAccessException during Test creation +RefactoringTester.InvocationTargetException=InvocationTargetException during Test creation +RefactoringTester.NotNamed=Not Named diff --git a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/refactoring/rename/RefactoringTests.java b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/refactoring/rename/RefactoringTests.java new file mode 100644 index 00000000000..644c53f65d4 --- /dev/null +++ b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/refactoring/rename/RefactoringTests.java @@ -0,0 +1,268 @@ +/******************************************************************************* + * Copyright (c) 2005, 2007 Wind River Systems, Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Markus Schorn - initial API and implementation + ******************************************************************************/ + +package org.eclipse.cdt.ui.tests.refactoring.rename; + +import java.io.StringWriter; + +import org.eclipse.cdt.core.tests.BaseTestFramework; +import org.eclipse.cdt.internal.core.dom.SavedCodeReaderFactory; +import org.eclipse.core.resources.IFile; +import org.eclipse.ltk.core.refactoring.Change; +import org.eclipse.ltk.core.refactoring.CompositeChange; +import org.eclipse.ltk.core.refactoring.RefactoringStatus; +import org.eclipse.ltk.core.refactoring.RefactoringStatusEntry; +import org.eclipse.ltk.core.refactoring.TextEditChangeGroup; +import org.eclipse.ltk.core.refactoring.TextFileChange; +import org.eclipse.search.internal.core.text.FileCharSequenceProvider; +import org.eclipse.text.edits.MultiTextEdit; +import org.eclipse.text.edits.ReplaceEdit; +import org.eclipse.text.edits.TextEdit; +import org.eclipse.text.edits.TextEditGroup; + + +/** + * @author markus.schorn@windriver.com + */ +public class RefactoringTests extends BaseTestFramework { + private int fBufferSize; + + public RefactoringTests() { + } + + public RefactoringTests(String name) { + super(name); + } + + protected void setUp() throws Exception { + super.setUp(); + fBufferSize= FileCharSequenceProvider.BUFFER_SIZE; + FileCharSequenceProvider.BUFFER_SIZE= 1024*4; + } + + protected void tearDown() throws Exception { + super.tearDown(); + SavedCodeReaderFactory.getInstance().getCodeReaderCache().flush(); + FileCharSequenceProvider.BUFFER_SIZE= fBufferSize; + } + + protected void assertTotalChanges(int numChanges, Change changes) throws Exception { + assertTotalChanges(numChanges, 0, 0, changes); + } + + protected void assertTotalChanges(int numChanges, int potChanges, int commentCh, + Change changes) throws Exception { + int count[]= {0,0,0}; + if( changes != null ) { + countChanges( changes, count); + } + assertEquals( numChanges, count[0] ); + assertEquals("potential changes: ", potChanges, count[1]); //$NON-NLS-1$ + assertEquals("comment changes: ", commentCh, count[2]); //$NON-NLS-1$ + } + + private void countChanges(Change change, int[] count) { + if( change instanceof CompositeChange ){ + Change [] children = ((CompositeChange) change).getChildren(); + for( int i = 0; i < children.length; i++ ){ + countChanges( children[i], count); + } + } else if( change instanceof TextFileChange ){ + TextFileChange tfc= (TextFileChange) change; + TextEditChangeGroup[] tecgs= tfc.getTextEditChangeGroups(); + for (int i = 0; i < tecgs.length; i++) { + TextEditChangeGroup group = tecgs[i]; + countChanges(group, count); + } + } + } + + private void countChanges(TextEditChangeGroup edit, int[] count) { + String name= edit.getName(); + if (name.indexOf("potential") != -1) { //$NON-NLS-1$ + count[1]++; + } + else if (name.indexOf("comment") != -1) { //$NON-NLS-1$ + count[2]++; + } + else { + count[0]++; + } + } + + protected void assertChange(Change changes, IFile file, int startOffset, int numChars, String newText) throws Exception { + assertChange(changes, file, startOffset, numChars, newText, false); + } + + protected void assertChange(Change changes, IFile file, int startOffset, int numChars, String newText, boolean potential) throws Exception { + boolean found = false; + if( changes != null && changes instanceof CompositeChange ){ + found = checkCompositeChange( (CompositeChange) changes, file, startOffset, numChars, newText, potential); + } + + if( !found ) { + fail ("Rename at offset " + startOffset + " in \"" + file.getLocation() + "\" not found."); //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$ + assertFalse( true ); + } + } + + private boolean checkCompositeChange(CompositeChange composite, IFile file, int startOffset, int numChars, String newText, boolean potential) { + boolean found = false; + Change [] children = composite.getChildren(); + for( int i = 0; i < children.length; i++ ){ + if( children[i] instanceof CompositeChange ) + found = checkCompositeChange( (CompositeChange) children[i], file, startOffset, numChars, newText, potential); + else if( children[i] instanceof TextFileChange ){ + TextFileChange tuChange = (TextFileChange) children[i]; + if( tuChange.getFile().toString().equals( file.toString() ) ){ + found = checkTranslationUnitChange( tuChange, startOffset, numChars, newText, potential ); + } + } + if( found ) + return found; + } + return found; + } + + private boolean checkTranslationUnitChange(TextFileChange change, int startOffset, int numChars, String newText, boolean potential) { + TextEditChangeGroup[] groups= change.getTextEditChangeGroups(); + for (int i = 0; i < groups.length; i++) { + TextEditGroup group = groups[i].getTextEditGroup(); + if ((group.getName().indexOf("potential") != -1) == potential) { //$NON-NLS-1$ + TextEdit[] edits= group.getTextEdits(); + if (checkTextEdits(edits, startOffset, numChars, newText)) { + return true; + } + } + } + return false; + } + + private boolean checkTextEdit(TextEdit edit, int startOffset, int numChars, String newText) { + if (edit instanceof MultiTextEdit) { + if (checkTextEdits(((MultiTextEdit) edit).getChildren(), + startOffset, numChars, newText)) { + return true; + } + } + else if (edit instanceof ReplaceEdit) { + if (checkReplaceEdit((ReplaceEdit) edit, startOffset, numChars, newText ) ) { + return true; + } + } + return false; + } + + private boolean checkTextEdits(TextEdit[] edits, int startOffset, int numChars, String newText) { + for (int i = 0; i < edits.length; i++) { + TextEdit edit = edits[i]; + if (checkTextEdit(edit, startOffset, numChars, newText)) { + return true; + } + } + return false; + } + + private boolean checkReplaceEdit(ReplaceEdit edit, int startOffset, int numChars, String newText) { + return ( edit.getOffset() == startOffset && edit.getLength() == numChars && edit.getText().equals( newText ) ); + } + + protected IFile createCppFwdDecls(String fileName) throws Exception { + StringWriter writer = new StringWriter(); + writer.write( "class class_fwd; \n"); //$NON-NLS-1$ + writer.write( "struct struct_fwd; \n"); //$NON-NLS-1$ + writer.write( "union union_fwd; \n"); //$NON-NLS-1$ + writer.write( "int func_proto(); \n"); //$NON-NLS-1$ + writer.write( "int func_proto_ov(); \n"); //$NON-NLS-1$ + writer.write( "int func_proto_ov(int); \n"); //$NON-NLS-1$ + writer.write( "int func_proto_ov(int*); \n"); //$NON-NLS-1$ + writer.write( "extern int extern_var; \n"); //$NON-NLS-1$ + String contents = writer.toString(); + return importFile(fileName, contents ); + } + + protected IFile createCFwdDecls(String fileName) throws Exception { + StringWriter writer = new StringWriter(); + writer.write( "struct struct_fwd; \n"); //$NON-NLS-1$ + writer.write( "union union_fwd; \n"); //$NON-NLS-1$ + writer.write( "int func_proto(); \n"); //$NON-NLS-1$ + writer.write( "extern int extern_var; \n"); //$NON-NLS-1$ + String contents = writer.toString(); + return importFile(fileName, contents ); + } + + protected IFile createCppDefs(String fileName) throws Exception { + StringWriter writer = new StringWriter(); + writer.write( "class class_def { \n"); //$NON-NLS-1$ + writer.write( "public: \n"); //$NON-NLS-1$ + writer.write( " int member; \n"); //$NON-NLS-1$ + writer.write( " static int static_member; \n"); //$NON-NLS-1$ + writer.write( " void method(int par); \n"); //$NON-NLS-1$ + writer.write( " void static_method(int par); \n"); //$NON-NLS-1$ + writer.write( " int method_ov(); \n"); //$NON-NLS-1$ + writer.write( " int method_ov(int); \n"); //$NON-NLS-1$ + writer.write( " int method_ov(int*); \n"); //$NON-NLS-1$ + writer.write( "}; \n"); //$NON-NLS-1$ + writer.write( "struct struct_def { \n"); //$NON-NLS-1$ + writer.write( " int st_member; \n"); //$NON-NLS-1$ + writer.write( "}; \n"); //$NON-NLS-1$ + writer.write( "union union_def { \n"); //$NON-NLS-1$ + writer.write( " int un_member; \n"); //$NON-NLS-1$ + writer.write( "}; \n"); //$NON-NLS-1$ + writer.write( "typedef int typedef_def; \n"); //$NON-NLS-1$ + writer.write( "namespace namespace_def{}; \n"); //$NON-NLS-1$ + writer.write( "enum enum_def { \n"); //$NON-NLS-1$ + writer.write( " enum_item }; \n"); //$NON-NLS-1$ + writer.write( "int func_def() {} \n"); //$NON-NLS-1$ + writer.write( "int func_def_ov() {} \n"); //$NON-NLS-1$ + writer.write( "int func_def_ov(int){} \n"); //$NON-NLS-1$ + writer.write( "int func_def_ov(int*){} \n"); //$NON-NLS-1$ + writer.write( "int var_def; \n"); //$NON-NLS-1$ + String contents = writer.toString(); + return importFile(fileName, contents ); + } + + protected IFile createCDefs(String fileName) throws Exception { + StringWriter writer = new StringWriter(); + writer.write( "struct struct_def { \n"); //$NON-NLS-1$ + writer.write( " int st_member; \n"); //$NON-NLS-1$ + writer.write( "}; \n"); //$NON-NLS-1$ + writer.write( "union union_def { \n"); //$NON-NLS-1$ + writer.write( " int un_member; \n"); //$NON-NLS-1$ + writer.write( "}; \n"); //$NON-NLS-1$ + writer.write( "typedef int typedef_def; \n"); //$NON-NLS-1$ + writer.write( "enum enum_def { \n"); //$NON-NLS-1$ + writer.write( " enum_item }; \n"); //$NON-NLS-1$ + writer.write( "int func_def() {} \n"); //$NON-NLS-1$ + writer.write( "int var_def; \n"); //$NON-NLS-1$ + String contents = writer.toString(); + return importFile(fileName, contents ); + } + + protected void assertRefactoringError(RefactoringStatus status, String msg) { + RefactoringStatusEntry e= status.getEntryMatchingSeverity(RefactoringStatus.ERROR); + assertNotNull("Expected refactoring error!", e); //$NON-NLS-1$ + assertEquals(msg, e.getMessage()); + } + + protected void assertRefactoringWarning(RefactoringStatus status, String msg) { + RefactoringStatusEntry e= status.getEntryMatchingSeverity(RefactoringStatus.WARNING); + assertNotNull("Expected refactoring warning!", e); //$NON-NLS-1$ + assertEquals(msg, e.getMessage()); + } + + protected void assertRefactoringOk(RefactoringStatus status) { + assertTrue("Expected refactoring status ok: " + //$NON-NLS-1$ + status.getMessageMatchingSeverity(status.getSeverity()), + status.getSeverity()==RefactoringStatus.OK); + } + +} diff --git a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/refactoring/rename/RenameFunctionTests.java b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/refactoring/rename/RenameFunctionTests.java new file mode 100644 index 00000000000..565d363e755 --- /dev/null +++ b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/refactoring/rename/RenameFunctionTests.java @@ -0,0 +1,819 @@ +/******************************************************************************* + * Copyright (c) 2005, 2007 Wind River Systems, Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Markus Schorn - initial API and implementation + *******************************************************************************/ + +package org.eclipse.cdt.ui.tests.refactoring.rename; + +import java.io.StringWriter; + +import junit.framework.Test; +import junit.framework.TestSuite; + +import org.eclipse.core.resources.IFile; +import org.eclipse.ltk.core.refactoring.Change; +import org.eclipse.ltk.core.refactoring.RefactoringStatus; + +/** + * @author markus.schorn@windriver.com + */ +public class RenameFunctionTests extends RenameTests { + + public RenameFunctionTests(String name) { + super(name); + } + public static Test suite(){ + return suite(true); + } + public static Test suite( boolean cleanup ) { + TestSuite suite = new TestSuite(RenameFunctionTests.class); + + if (cleanup) { + suite.addTest( new RefactoringTests("cleanupProject") ); //$NON-NLS-1$ + } + return suite; + } + + public void testFunctionNameConflicts() throws Exception { + createCppFwdDecls("cpp_fwd.hh"); //$NON-NLS-1$ + createCppDefs("cpp_def.hh"); //$NON-NLS-1$ + StringWriter writer = new StringWriter(); + writer.write("#include \"cpp_fwd.hh\" \n"); //$NON-NLS-1$ + writer.write("#include \"cpp_def.hh\" \n"); //$NON-NLS-1$ + writer.write("int v1(); int v2(); int v3(); \n"); //$NON-NLS-1$ + writer.write("static int s1(); \n"); //$NON-NLS-1$ + writer.write("static int s2(); \n"); //$NON-NLS-1$ + writer.write("void f(int par1){ \n"); //$NON-NLS-1$ + writer.write(" { \n"); //$NON-NLS-1$ + writer.write(" int w1; v1(); \n"); //$NON-NLS-1$ + writer.write(" } \n"); //$NON-NLS-1$ + writer.write("} \n"); //$NON-NLS-1$ + writer.write("void class_def::method(int par2) { \n"); //$NON-NLS-1$ + writer.write(" { \n"); //$NON-NLS-1$ + writer.write(" int w2; v2(); \n"); //$NON-NLS-1$ + writer.write(" } \n"); //$NON-NLS-1$ + writer.write("} \n"); //$NON-NLS-1$ + writer.write("static void class_def::static_method(int par3) { \n"); //$NON-NLS-1$ + writer.write(" { \n"); //$NON-NLS-1$ + writer.write(" int w3; v3(); \n"); //$NON-NLS-1$ + writer.write(" } \n"); //$NON-NLS-1$ + writer.write("} \n"); //$NON-NLS-1$ + String contents = writer.toString(); + IFile cpp= importFile("test.cpp", contents ); //$NON-NLS-1$ + + writer = new StringWriter(); + writer.write( "static int static_other_file(); \n" ); //$NON-NLS-1$ + importFile( "other.cpp", writer.toString() ); //$NON-NLS-1$ + + + int offset1= contents.indexOf("v1"); //$NON-NLS-1$ + int offset2= contents.indexOf("v2"); //$NON-NLS-1$ + int offset3= contents.indexOf("v3"); //$NON-NLS-1$ + + // conflicting renamings + RefactoringStatus status= checkConditions(cpp, offset1, "w1"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Shadowing \n" + + "New element: w1 \n" + + "Conflicting element type: Local variable"); //$NON-NLS-1$ + status= checkConditions(cpp, contents.indexOf("par1"), "v1"); //$NON-NLS-1$ //$NON-NLS-2$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Shadowing \n" + + "New element: v1 \n" + + "Conflicting element type: Global function"); //$NON-NLS-1$ + status= checkConditions(cpp, offset1, "par1"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Shadowing \n" + + "New element: par1 \n" + + "Conflicting element type: Parameter"); //$NON-NLS-1$ + status= checkConditions(cpp, offset1, "extern_var"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: extern_var \n" + + "Conflicting element type: Global variable"); //$NON-NLS-1$ + status= checkConditions(cpp, offset1, "var_def"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: var_def \n" + + "Conflicting element type: Global variable"); //$NON-NLS-1$ + status= checkConditions(cpp, offset1, "enum_item"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: enum_item \n" + + "Conflicting element type: Enumerator"); //$NON-NLS-1$ + + status= checkConditions(cpp, offset2, "w2"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Shadowing \n" + + "New element: w2 \n" + + "Conflicting element type: Local variable"); //$NON-NLS-1$ + status= checkConditions(cpp, offset2, "par2"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Shadowing \n" + + "New element: par2 \n" + + "Conflicting element type: Parameter"); //$NON-NLS-1$ + status= checkConditions(cpp, offset2, "extern_var"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: extern_var \n" + + "Conflicting element type: Global variable"); //$NON-NLS-1$ + status= checkConditions(cpp, offset2, "var_def"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: var_def \n" + + "Conflicting element type: Global variable"); //$NON-NLS-1$ + status= checkConditions(cpp, offset2, "enum_item"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: enum_item \n" + + "Conflicting element type: Enumerator"); //$NON-NLS-1$ + + status= checkConditions(cpp, offset3, "w3"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Shadowing \n" + + "New element: w3 \n" + + "Conflicting element type: Local variable"); //$NON-NLS-1$ + status= checkConditions(cpp, offset3, "par3"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Shadowing \n" + + "New element: par3 \n" + + "Conflicting element type: Parameter"); //$NON-NLS-1$ + status= checkConditions(cpp, offset3, "extern_var"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: extern_var \n" + + "Conflicting element type: Global variable"); //$NON-NLS-1$ + status= checkConditions(cpp, offset3, "var_def"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: var_def \n" + + "Conflicting element type: Global variable"); //$NON-NLS-1$ + status= checkConditions(cpp, offset3, "enum_item"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: enum_item \n" + + "Conflicting element type: Enumerator"); //$NON-NLS-1$ + + // renamings depending on scope + status= checkConditions(cpp, offset1, "member"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "method"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "static_member"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "static_method"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset2, "member"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Shadowing \n" + + "New element: member \n" + + "Conflicting element type: Field"); //$NON-NLS-1$ + status= checkConditions(cpp, offset2, "method"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Shadowing \n" + + "New element: method \n" + + "Conflicting element type: Method"); //$NON-NLS-1$ + status= checkConditions(cpp, offset2, "static_member"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Shadowing \n" + + "New element: static_member \n" + + "Conflicting element type: Field"); //$NON-NLS-1$ + status= checkConditions(cpp, offset2, "static_method"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Shadowing \n" + + "New element: static_method \n" + + "Conflicting element type: Method"); //$NON-NLS-1$ +// lookup inside a static method also returns non-static members +// we may want to have a check whether a binding is accessible or not. + +// status= checkConditions(cpp, offset3, "member"); //$NON-NLS-1$ +// assertRefactoringOk(status); +// status= checkConditions(cpp, offset3, "method"); //$NON-NLS-1$ +// assertRefactoringOk(status); + status= checkConditions(cpp, offset3, "static_member"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Shadowing \n" + + "New element: static_member \n" + + "Conflicting element type: Field"); //$NON-NLS-1$ + status= checkConditions(cpp, offset3, "static_method"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Shadowing \n" + + "New element: static_method \n" + + "Conflicting element type: Method"); //$NON-NLS-1$ + + // renamings conflicting with global stuff. + status= checkConditions(cpp, offset1, "func_proto"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: func_proto \n" + + "Conflicting element type: Global function"); //$NON-NLS-1$ + status= checkConditions(cpp, offset1, "func_proto_ov"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: func_proto_ov \n" + + "Conflicting element type: Global function"); //$NON-NLS-1$ + status= checkConditions(cpp, offset1, "func_def"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: func_def \n" + + "Conflicting element type: Global function"); //$NON-NLS-1$ + // would be good to see an error here + status= checkConditions(cpp, offset1, "func_def_ov"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: func_def_ov \n" + + "Conflicting element type: Global function"); //$NON-NLS-1$ + status= checkConditions(cpp, offset2, "func_proto"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: func_proto \n" + + "Conflicting element type: Global function"); //$NON-NLS-1$ + status= checkConditions(cpp, offset2, "func_proto_ov"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: func_proto_ov \n" + + "Conflicting element type: Global function"); //$NON-NLS-1$ + status= checkConditions(cpp, offset2, "func_def"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: func_def \n" + + "Conflicting element type: Global function"); //$NON-NLS-1$ + // would be good to see an error here + status= checkConditions(cpp, offset2, "func_def_ov"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: func_def_ov \n" + + "Conflicting element type: Global function"); //$NON-NLS-1$ + status= checkConditions(cpp, offset3, "func_proto"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: func_proto \n" + + "Conflicting element type: Global function"); //$NON-NLS-1$ + status= checkConditions(cpp, offset3, "func_proto_ov"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: func_proto_ov \n" + + "Conflicting element type: Global function"); //$NON-NLS-1$ + status= checkConditions(cpp, offset3, "func_def"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: func_def \n" + + "Conflicting element type: Global function"); //$NON-NLS-1$ + status= checkConditions(cpp, offset3, "func_def_ov"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: func_def_ov \n" + + "Conflicting element type: Global function"); //$NON-NLS-1$ + + // renamings that are ok. + status= checkConditions(cpp, offset1, "class_fwd"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "struct_fwd"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "union_fwd"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "class_def"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Shadowing \n" + + "New element: class_def \n" + + "Conflicting element type: Constructor"); //$NON-NLS-1$ + status= checkConditions(cpp, offset1, "struct_def"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "union_def"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "enum_def"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "typedef_def"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "namespace_def"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "st_member"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "un_member"); //$NON-NLS-1$ + assertRefactoringOk(status); + + status= checkConditions(cpp, offset2, "class_fwd"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset2, "struct_fwd"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset2, "union_fwd"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset2, "class_def"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Shadowing \n" + + "New element: class_def \n" + + "Conflicting element type: Constructor"); //$NON-NLS-1$ + status= checkConditions(cpp, offset2, "struct_def"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset2, "union_def"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset2, "enum_def"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset2, "typedef_def"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset2, "namespace_def"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset2, "st_member"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset2, "un_member"); //$NON-NLS-1$ + assertRefactoringOk(status); + + status= checkConditions(cpp, offset3, "class_fwd"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset3, "struct_fwd"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset3, "union_fwd"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset3, "class_def"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Shadowing \n" + + "New element: class_def \n" + + "Conflicting element type: Constructor"); //$NON-NLS-1$ + status= checkConditions(cpp, offset3, "struct_def"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset3, "union_def"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset3, "enum_def"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset3, "typedef_def"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset3, "namespace_def"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset3, "st_member"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset3, "un_member"); //$NON-NLS-1$ + assertRefactoringOk(status); + + // file static stuff + status= checkConditions(cpp, contents.indexOf("s1"), "s2"); //$NON-NLS-1$ //$NON-NLS-2$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: s2 \n" + + "Conflicting element type: File static function"); //$NON-NLS-1$ + + status= checkConditions(cpp, contents.indexOf("s1"), "static_other_file"); //$NON-NLS-1$ //$NON-NLS-2$ + assertRefactoringOk(status); + } + + public void testFunctionsPlainC() throws Exception { + createCFwdDecls("c_fwd.h"); //$NON-NLS-1$ + createCDefs("c_def.h"); //$NON-NLS-1$ + StringWriter writer = new StringWriter(); + writer.write("#include \"c_fwd.h\" \n"); //$NON-NLS-1$ + writer.write("#include \"c_def.h\" \n"); //$NON-NLS-1$ + writer.write("int v1(); int v2(); int v3(); \n"); //$NON-NLS-1$ + writer.write("int func_proto(); \n"); //$NON-NLS-1$ + writer.write("static int s2(); \n"); //$NON-NLS-1$ + writer.write("void func_def(){ \n"); //$NON-NLS-1$ + writer.write(" int w1; v1(); \n"); //$NON-NLS-1$ + writer.write("} \n"); //$NON-NLS-1$ + String contents = writer.toString(); + IFile cpp= importFile("test.c", contents ); //$NON-NLS-1$ + + int offset1= contents.indexOf("func_proto"); //$NON-NLS-1$ + Change change= getRefactorChanges(cpp, offset1, "xxx"); //$NON-NLS-1$ + assertTotalChanges(2, change); + + offset1= contents.indexOf("func_def"); //$NON-NLS-1$ + change= getRefactorChanges(cpp, offset1, "xxx"); //$NON-NLS-1$ + assertTotalChanges(2, change); + } + + + public void testFunctionNameConflictsPlainC() throws Exception { + createCFwdDecls("c_fwd.h"); //$NON-NLS-1$ + createCDefs("c_def.h"); //$NON-NLS-1$ + StringWriter writer = new StringWriter(); + writer.write("#include \"c_fwd.h\" \n"); //$NON-NLS-1$ + writer.write("#include \"c_def.h\" \n"); //$NON-NLS-1$ + writer.write("int v1(); int v2(); int v3(); \n"); //$NON-NLS-1$ + writer.write("static int s1(); \n"); //$NON-NLS-1$ + writer.write("static int s2(); \n"); //$NON-NLS-1$ + writer.write("void f(int par1){ \n"); //$NON-NLS-1$ + writer.write(" int w1; v1(); \n"); //$NON-NLS-1$ + writer.write("} \n"); //$NON-NLS-1$ + String contents = writer.toString(); + IFile cpp= importFile("test.c", contents ); //$NON-NLS-1$ + + writer = new StringWriter(); + writer.write( "static int static_other_file(); \n" ); //$NON-NLS-1$ + importFile( "other.c", writer.toString() ); //$NON-NLS-1$ + + + int offset1= contents.indexOf("v1"); //$NON-NLS-1$ + + // conflicting renamings + RefactoringStatus status= checkConditions(cpp, offset1, "w1"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Shadowing \n" + + "New element: w1 \n" + + "Conflicting element type: Local variable"); //$NON-NLS-1$ + status= checkConditions(cpp, contents.indexOf("par1"), "v1"); //$NON-NLS-1$ //$NON-NLS-2$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Shadowing \n" + + "New element: v1 \n" + + "Conflicting element type: Global function"); //$NON-NLS-1$ + status= checkConditions(cpp, offset1, "par1"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Shadowing \n" + + "New element: par1 \n" + + "Conflicting element type: Parameter"); //$NON-NLS-1$ + status= checkConditions(cpp, offset1, "extern_var"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: extern_var \n" + + "Conflicting element type: Global variable"); //$NON-NLS-1$ + status= checkConditions(cpp, offset1, "var_def"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: var_def \n" + + "Conflicting element type: Global variable"); //$NON-NLS-1$ + status= checkConditions(cpp, offset1, "enum_item"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: enum_item \n" + + "Conflicting element type: Enumerator"); //$NON-NLS-1$ + + // renamings conflicting with global stuff. + status= checkConditions(cpp, offset1, "func_proto"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: func_proto \n" + + "Conflicting element type: Global function"); //$NON-NLS-1$ + status= checkConditions(cpp, offset1, "func_def"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: func_def \n" + + "Conflicting element type: Global function"); //$NON-NLS-1$ + + // renamings that are ok. + status= checkConditions(cpp, offset1, "struct_fwd"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "union_fwd"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "struct_def"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "union_def"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "enum_def"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "typedef_def"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "st_member"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "un_member"); //$NON-NLS-1$ + assertRefactoringOk(status); + + // file static stuff + status= checkConditions(cpp, contents.indexOf("s1"), "s2"); //$NON-NLS-1$ //$NON-NLS-2$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: s2 \n" + + "Conflicting element type: File static function"); //$NON-NLS-1$ + + status= checkConditions(cpp, contents.indexOf("s1"), "static_other_file"); //$NON-NLS-1$ //$NON-NLS-2$ + assertRefactoringOk(status); + } + + public void testMethodNameConflicts1() throws Exception { + createCppFwdDecls("cpp_fwd.hh"); //$NON-NLS-1$ + createCppDefs("cpp_def.hh"); //$NON-NLS-1$ + StringWriter writer = new StringWriter(); + writer.write("#include \"cpp_fwd.hh\" \n"); //$NON-NLS-1$ + writer.write("#include \"cpp_def.hh\" \n"); //$NON-NLS-1$ + writer.write("class Dummy { \n"); //$NON-NLS-1$ + writer.write(" int v1(); int v2(); \n"); //$NON-NLS-1$ + writer.write(" int member; \n"); //$NON-NLS-1$ + writer.write(" int method(int); \n"); //$NON-NLS-1$ + writer.write(" int method_samesig(); \n"); //$NON-NLS-1$ + writer.write(" static int static_method(int); \n"); //$NON-NLS-1$ + writer.write(" static int static_member; \n"); //$NON-NLS-1$ + writer.write("}; \n"); //$NON-NLS-1$ + writer.write("int Dummy::method(int par1) { \n"); //$NON-NLS-1$ + writer.write(" { \n"); //$NON-NLS-1$ + writer.write(" int w1; v1(); \n"); //$NON-NLS-1$ + writer.write(" } \n"); //$NON-NLS-1$ + writer.write("} \n"); //$NON-NLS-1$ + writer.write("static int Dummy::static_method(int par2) { \n"); //$NON-NLS-1$ + writer.write(" { \n"); //$NON-NLS-1$ + writer.write(" int w2; v2(); \n"); //$NON-NLS-1$ + writer.write(" } \n"); //$NON-NLS-1$ + writer.write("} \n"); //$NON-NLS-1$ + String contents = writer.toString(); + IFile cpp= importFile("test.cpp", contents ); //$NON-NLS-1$ + + int offset1= contents.indexOf("v1"); //$NON-NLS-1$ + int offset2= contents.indexOf("v2"); //$NON-NLS-1$ + + // conflicting renamings + RefactoringStatus status= checkConditions(cpp, offset1, "w1"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Shadowing \n" + + "New element: w1 \n" + + "Conflicting element type: Local variable"); //$NON-NLS-1$ + status= checkConditions(cpp, contents.indexOf("w1"), "v1"); //$NON-NLS-1$ //$NON-NLS-2$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Shadowing \n" + + "New element: v1 \n" + + "Conflicting element type: Method"); //$NON-NLS-1$ + status= checkConditions(cpp, contents.indexOf("par1"), "v1"); //$NON-NLS-1$ //$NON-NLS-2$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Shadowing \n" + + "New element: v1 \n" + + "Conflicting element type: Method"); //$NON-NLS-1$ + status= checkConditions(cpp, offset1, "par1"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Shadowing \n" + + "New element: par1 \n" + + "Conflicting element type: Parameter"); //$NON-NLS-1$ + status= checkConditions(cpp, offset1, "extern_var"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Shadowing \n" + + "New element: extern_var \n" + + "Conflicting element type: Global variable"); //$NON-NLS-1$ + status= checkConditions(cpp, offset1, "var_def"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Shadowing \n" + + "New element: var_def \n" + + "Conflicting element type: Global variable"); //$NON-NLS-1$ + status= checkConditions(cpp, offset1, "enum_item"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Shadowing \n" + + "New element: enum_item \n" + + "Conflicting element type: Enumerator"); //$NON-NLS-1$ + + status= checkConditions(cpp, offset2, "w2"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Shadowing \n" + + "New element: w2 \n" + + "Conflicting element type: Local variable"); //$NON-NLS-1$ + status= checkConditions(cpp, offset2, "par2"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Shadowing \n" + + "New element: par2 \n" + + "Conflicting element type: Parameter"); //$NON-NLS-1$ + status= checkConditions(cpp, offset2, "extern_var"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Shadowing \n" + + "New element: extern_var \n" + + "Conflicting element type: Global variable"); //$NON-NLS-1$ + status= checkConditions(cpp, offset2, "var_def"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Shadowing \n" + + "New element: var_def \n" + + "Conflicting element type: Global variable"); //$NON-NLS-1$ + status= checkConditions(cpp, offset2, "enum_item"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Shadowing \n" + + "New element: enum_item \n" + + "Conflicting element type: Enumerator"); //$NON-NLS-1$ + + + status= checkConditions(cpp, offset2, "member"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: member \n" + + "Conflicting element type: Field"); //$NON-NLS-1$ + status= checkConditions(cpp, offset2, "method"); //$NON-NLS-1$ + assertRefactoringWarning(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Overloading \n" + + "New element: method \n" + + "Conflicting element type: Method"); //$NON-NLS-1$ + status= checkConditions(cpp, offset2, "method_samesig"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: method_samesig \n" + + "Conflicting element type: Method"); //$NON-NLS-1$ + status= checkConditions(cpp, offset2, "static_member"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: static_member \n" + + "Conflicting element type: Field"); //$NON-NLS-1$ + status= checkConditions(cpp, offset2, "static_method"); //$NON-NLS-1$ + assertRefactoringWarning(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Overloading \n" + + "New element: static_method \n" + + "Conflicting element type: Method"); //$NON-NLS-1$ + } + + public void testMethodNameConflicts2() throws Exception { + createCppFwdDecls("cpp_fwd.hh"); //$NON-NLS-1$ + createCppDefs("cpp_def.hh"); //$NON-NLS-1$ + StringWriter writer = new StringWriter(); + writer.write("#include \"cpp_fwd.hh\" \n"); //$NON-NLS-1$ + writer.write("#include \"cpp_def.hh\" \n"); //$NON-NLS-1$ + writer.write("class Dummy { \n"); //$NON-NLS-1$ + writer.write(" int v1(), v2(), v3(); \n"); //$NON-NLS-1$ + writer.write("}; \n"); //$NON-NLS-1$ + writer.write("Dummy d; \n"); //$NON-NLS-1$ + writer.write("void f(int par1){ \n"); //$NON-NLS-1$ + writer.write(" { \n"); //$NON-NLS-1$ + writer.write(" int w1; d.v1(); \n"); //$NON-NLS-1$ + writer.write(" } \n"); //$NON-NLS-1$ + writer.write("} \n"); //$NON-NLS-1$ + writer.write("void class_def::method(int par2) { \n"); //$NON-NLS-1$ + writer.write(" { \n"); //$NON-NLS-1$ + writer.write(" int w2; d.v2(); \n"); //$NON-NLS-1$ + writer.write(" } \n"); //$NON-NLS-1$ + writer.write("} \n"); //$NON-NLS-1$ + writer.write("static void class_def::static_method(int par3) { \n"); //$NON-NLS-1$ + writer.write(" { \n"); //$NON-NLS-1$ + writer.write(" int w3; d.v3(); \n"); //$NON-NLS-1$ + writer.write(" } \n"); //$NON-NLS-1$ + writer.write("} \n"); //$NON-NLS-1$ + String contents = writer.toString(); + IFile cpp= importFile("test.cpp", contents ); //$NON-NLS-1$ + + int offset1= contents.indexOf("v1"); //$NON-NLS-1$ + int offset2= contents.indexOf("v2"); //$NON-NLS-1$ + int offset3= contents.indexOf("v3"); //$NON-NLS-1$ + + // conflicting renamings + RefactoringStatus status= checkConditions(cpp, offset1, "w1"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "par1"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "extern_var"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "var_def"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "enum_item"); //$NON-NLS-1$ + assertRefactoringOk(status); + + status= checkConditions(cpp, offset2, "w2"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset2, "par2"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset2, "extern_var"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset2, "var_def"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset2, "enum_item"); //$NON-NLS-1$ + assertRefactoringOk(status); + + status= checkConditions(cpp, offset3, "w3"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset3, "par3"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset3, "extern_var"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset3, "var_def"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset3, "enum_item"); //$NON-NLS-1$ + assertRefactoringOk(status); + + // renamings depending on scope + status= checkConditions(cpp, offset1, "member"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "method"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "static_member"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "static_method"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset2, "member"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset2, "method"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset2, "static_member"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset2, "static_method"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset3, "static_member"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset3, "static_method"); //$NON-NLS-1$ + assertRefactoringOk(status); + + status= checkConditions(cpp, offset1, "func_proto"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "func_proto_ov"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "func_def"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "func_def_ov"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset2, "func_proto"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset2, "func_proto_ov"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset2, "func_def"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset2, "func_def_ov"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset3, "func_proto"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset3, "func_proto_ov"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset3, "func_def"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset3, "func_def_ov"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "class_fwd"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "struct_fwd"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "union_fwd"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "class_def"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "struct_def"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "union_def"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "enum_def"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "typedef_def"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "namespace_def"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "st_member"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "un_member"); //$NON-NLS-1$ + assertRefactoringOk(status); + + status= checkConditions(cpp, offset2, "class_fwd"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset2, "struct_fwd"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset2, "union_fwd"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset2, "class_def"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset2, "struct_def"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset2, "union_def"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset2, "enum_def"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset2, "typedef_def"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset2, "namespace_def"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset2, "st_member"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset2, "un_member"); //$NON-NLS-1$ + assertRefactoringOk(status); + + status= checkConditions(cpp, offset3, "class_fwd"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset3, "struct_fwd"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset3, "union_fwd"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset3, "class_def"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset3, "struct_def"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset3, "union_def"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset3, "enum_def"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset3, "typedef_def"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset3, "namespace_def"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset3, "st_member"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset3, "un_member"); //$NON-NLS-1$ + assertRefactoringOk(status); + } + + public void testBug72605() throws Exception { + StringWriter writer = new StringWriter(); + writer.write("class Foo { \n"); //$NON-NLS-1$ + writer.write(" void m1(int x=0); \n"); //$NON-NLS-1$ + writer.write("}; \n"); //$NON-NLS-1$ + writer.write("void Foo::m1(int x) {} \n"); //$NON-NLS-1$ + String contents = writer.toString(); + IFile cpp= importFile("test.cpp", contents ); //$NON-NLS-1$ + + int offset = contents.indexOf("m1") ; //$NON-NLS-1$ + int offset2= contents.indexOf("m1", offset+1) ; //$NON-NLS-1$ + Change changes = getRefactorChanges(cpp, offset, "z"); //$NON-NLS-1$ + assertTotalChanges( 2, changes ); + changes = getRefactorChanges(cpp, offset2, "z"); //$NON-NLS-1$ + assertTotalChanges( 2, changes ); + } + + public void testBug72732() throws Exception { + StringWriter writer = new StringWriter(); + writer.write("class Foo { \n"); //$NON-NLS-1$ + writer.write(" virtual void mthd() = 0;\n"); //$NON-NLS-1$ + writer.write("}; \n"); //$NON-NLS-1$ + writer.write("class Moo: public Foo{ \n"); //$NON-NLS-1$ + writer.write(" void mthd() = 0; \n"); //$NON-NLS-1$ + writer.write("}; \n"); //$NON-NLS-1$ + String contents = writer.toString(); + IFile cpp= importFile("test.cpp", contents ); //$NON-NLS-1$ + int offset = contents.indexOf("mthd") ; //$NON-NLS-1$ + offset= contents.indexOf("mthd", offset+1) ; //$NON-NLS-1$ + RefactoringStatus status= checkConditions(cpp, offset, "xxx"); //$NON-NLS-1$ + assertRefactoringWarning(status, "Renaming a virtual method. Consider renaming the base and derived class methods (if any)."); //$NON-NLS-1$ + } +} diff --git a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/refactoring/rename/RenameMacroTests.java b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/refactoring/rename/RenameMacroTests.java new file mode 100644 index 00000000000..a0098de9af8 --- /dev/null +++ b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/refactoring/rename/RenameMacroTests.java @@ -0,0 +1,223 @@ +/******************************************************************************* + * Copyright (c) 2005, 2007 Wind River Systems, Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Markus Schorn - initial API and implementation + *******************************************************************************/ + +package org.eclipse.cdt.ui.tests.refactoring.rename; + +import java.io.StringWriter; + +import junit.framework.Test; +import junit.framework.TestSuite; + +import org.eclipse.core.resources.IFile; +import org.eclipse.ltk.core.refactoring.Change; +import org.eclipse.ltk.core.refactoring.RefactoringStatus; + +/** + * @author markus.schorn@windriver.com + */ +public class RenameMacroTests extends RenameTests { + + public RenameMacroTests(String name) { + super(name); + } + public static Test suite(){ + return suite(true); + } + public static Test suite( boolean cleanup ) { + TestSuite suite = new TestSuite(RenameMacroTests.class); + if (cleanup) { + suite.addTest( new RefactoringTests("cleanupProject") ); //$NON-NLS-1$ + } + return suite; + } + + + public void testMacroRename() throws Exception { + StringWriter writer = new StringWriter(); + writer.write("#define HALLO x \n"); //$NON-NLS-1$ + writer.write("class v1 { \n"); //$NON-NLS-1$ + writer.write(" int HALLO; \n"); //$NON-NLS-1$ + writer.write("}; \n"); //$NON-NLS-1$ + writer.write("class HALLO { \n"); //$NON-NLS-1$ + writer.write(" int v; \n"); //$NON-NLS-1$ + writer.write("}; \n"); //$NON-NLS-1$ + writer.write("class v3 { \n"); //$NON-NLS-1$ + writer.write(" int v; \n"); //$NON-NLS-1$ + writer.write("}; \n"); //$NON-NLS-1$ + writer.write("class v4 { \n"); //$NON-NLS-1$ + writer.write(" int HALLO(); \n"); //$NON-NLS-1$ + writer.write("}; \n"); //$NON-NLS-1$ + writer.write("int v4::HALLO(){} \n"); //$NON-NLS-1$ + writer.write("void f(int par1){ \n"); //$NON-NLS-1$ + writer.write(" { \n"); //$NON-NLS-1$ + writer.write(" int HALLO; v1::v++; \n"); //$NON-NLS-1$ + writer.write(" } \n"); //$NON-NLS-1$ + writer.write("} \n"); //$NON-NLS-1$ + String contents = writer.toString(); + IFile cpp= importFile("test.cpp", contents ); //$NON-NLS-1$ + + int offset1= contents.indexOf("HALLO"); //$NON-NLS-1$ + int offset2= contents.indexOf("HALLO", offset1+1); //$NON-NLS-1$ + + Change ch= getRefactorChanges(cpp, offset1, "WELT"); //$NON-NLS-1$ + assertTotalChanges(6, ch); + int off= offset1; + assertChange(ch, cpp, off, 5, "WELT"); //$NON-NLS-1$ + off= contents.indexOf("HALLO", off+1); //$NON-NLS-1$ + assertChange(ch, cpp, off, 5, "WELT"); //$NON-NLS-1$ + off= contents.indexOf("HALLO", off+1); //$NON-NLS-1$ + assertChange(ch, cpp, off, 5, "WELT"); //$NON-NLS-1$ + off= contents.indexOf("HALLO", off+1); //$NON-NLS-1$ + assertChange(ch, cpp, off, 5, "WELT"); //$NON-NLS-1$ + off= contents.indexOf("HALLO", off+1); //$NON-NLS-1$ + assertChange(ch, cpp, off, 5, "WELT"); //$NON-NLS-1$ + off= contents.indexOf("HALLO", off+1); //$NON-NLS-1$ + assertChange(ch, cpp, off, 5, "WELT"); //$NON-NLS-1$ + off= contents.indexOf("HALLO", off+1); //$NON-NLS-1$ + + ch= getRefactorChanges(cpp, offset2, "WELT"); //$NON-NLS-1$ + assertTotalChanges(6, ch); + off= offset1; + assertChange(ch, cpp, off, 5, "WELT"); //$NON-NLS-1$ + off= contents.indexOf("HALLO", off+1); //$NON-NLS-1$ + assertChange(ch, cpp, off, 5, "WELT"); //$NON-NLS-1$ + off= contents.indexOf("HALLO", off+1); //$NON-NLS-1$ + assertChange(ch, cpp, off, 5, "WELT"); //$NON-NLS-1$ + off= contents.indexOf("HALLO", off+1); //$NON-NLS-1$ + assertChange(ch, cpp, off, 5, "WELT"); //$NON-NLS-1$ + off= contents.indexOf("HALLO", off+1); //$NON-NLS-1$ + assertChange(ch, cpp, off, 5, "WELT"); //$NON-NLS-1$ + off= contents.indexOf("HALLO", off+1); //$NON-NLS-1$ + assertChange(ch, cpp, off, 5, "WELT"); //$NON-NLS-1$ + off= contents.indexOf("HALLO", off+1); //$NON-NLS-1$ + } + + public void testMacroNameConflicts() throws Exception { + createCppFwdDecls("cpp_fwd.hh"); //$NON-NLS-1$ + createCppDefs("cpp_def.hh"); //$NON-NLS-1$ + StringWriter writer = new StringWriter(); + writer.write("#include \"cpp_fwd.hh\" \n"); //$NON-NLS-1$ + writer.write("#include \"cpp_def.hh\" \n"); //$NON-NLS-1$ + writer.write("#define MACRO 1 \n"); //$NON-NLS-1$ + writer.write("int v1(); int v2(); int v3(); \n"); //$NON-NLS-1$ + writer.write("static int s1(); \n"); //$NON-NLS-1$ + writer.write("static int s2(); \n"); //$NON-NLS-1$ + writer.write("void f(int par1){ \n"); //$NON-NLS-1$ + writer.write(" int w1; v1(); \n"); //$NON-NLS-1$ + writer.write("} \n"); //$NON-NLS-1$ + String contents = writer.toString(); + IFile cpp= importFile("test.cpp", contents ); //$NON-NLS-1$ + + writer = new StringWriter(); + writer.write( "static int static_other_file(); \n" ); //$NON-NLS-1$ + importFile( "other.cpp", writer.toString() ); //$NON-NLS-1$ + + + int offset1= contents.indexOf("MACRO"); //$NON-NLS-1$ + + // conflicting renamings + RefactoringStatus status= checkConditions(cpp, offset1, "w1"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Name conflict \n" + + "New element: w1 \n" + + "Conflicting element type: Local variable"); //$NON-NLS-1$ + status= checkConditions(cpp, contents.indexOf("par1"), "MACRO"); //$NON-NLS-1$ //$NON-NLS-2$ + assertRefactoringError(status, "'MACRO' conflicts with the name of an existing macro!"); //$NON-NLS-1$ + status= checkConditions(cpp, offset1, "par1"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Name conflict \n" + + "New element: par1 \n" + + "Conflicting element type: Parameter"); //$NON-NLS-1$ + status= checkConditions(cpp, offset1, "extern_var"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Name conflict \n" + + "New element: extern_var \n" + + "Conflicting element type: Global variable"); //$NON-NLS-1$ + status= checkConditions(cpp, offset1, "var_def"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Name conflict \n" + + "New element: var_def \n" + + "Conflicting element type: Global variable"); //$NON-NLS-1$ + status= checkConditions(cpp, offset1, "enum_item"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Name conflict \n" + + "New element: enum_item \n" + + "Conflicting element type: Enumerator"); //$NON-NLS-1$ + } + + public void testClassMacroClash() throws Exception { + StringWriter writer = new StringWriter(); + writer.write("class CC {int a;}; \n"); //$NON-NLS-1$ + String contents = writer.toString(); + IFile cpp= importFile("test.cpp", contents ); //$NON-NLS-1$ + + writer = new StringWriter(); + writer.write("#define CC mm \n"); //$NON-NLS-1$ + writer.write("int CC; \n"); //$NON-NLS-1$ + String contents2 = writer.toString(); + IFile cpp2= importFile("test2.cpp", contents2 ); //$NON-NLS-1$ + + int offset1= contents.indexOf("CC"); //$NON-NLS-1$ + Change ch= getRefactorChanges(cpp, offset1, "CCC"); //$NON-NLS-1$ + assertTotalChanges(1, ch); + + int offset2= contents2.indexOf("CC"); //$NON-NLS-1$ + ch= getRefactorChanges(cpp2, offset2, "CCC"); //$NON-NLS-1$ + assertTotalChanges(2, ch); + } + + public void testIncludeGuard() throws Exception { + StringWriter writer = new StringWriter(); + writer.write("#ifndef _guard \n"); //$NON-NLS-1$ + writer.write("#define _guard \n"); //$NON-NLS-1$ + writer.write(" int HALLO \n"); //$NON-NLS-1$ + writer.write("#endif /* _guard */ \n"); //$NON-NLS-1$ + String contents = writer.toString(); + IFile cpp= importFile("test.cpp", contents ); //$NON-NLS-1$ + + int offset1= contents.indexOf("_guard"); //$NON-NLS-1$ + int offset2= contents.indexOf("_guard", offset1+1); //$NON-NLS-1$ + Change ch= getRefactorChanges(cpp, offset2, "WELT"); //$NON-NLS-1$ + assertTotalChanges(2, 0, 1, ch); + int off= offset1; + assertChange(ch, cpp, off, 6, "WELT"); //$NON-NLS-1$ + off= contents.indexOf("_guard", off+1); //$NON-NLS-1$ + assertChange(ch, cpp, off, 6, "WELT"); //$NON-NLS-1$ + } + + public void testMacroParameters() throws Exception { + StringWriter writer = new StringWriter(); + writer.write("int var; \n"); //$NON-NLS-1$ + writer.write("#define M1(var) var \n"); //$NON-NLS-1$ + writer.write("#define M2(var, x) (var+x)*var \n"); //$NON-NLS-1$ + writer.write("#define M3 var \n"); //$NON-NLS-1$ + String contents = writer.toString(); + IFile cpp= importFile("test.cpp", contents ); //$NON-NLS-1$ + + int offset1= contents.indexOf("var"); //$NON-NLS-1$ + Change ch= getRefactorChanges(cpp, offset1, "xxx"); //$NON-NLS-1$ + assertTotalChanges(1, 1, 0, ch); + } + + public void testRenameMacroAsMacroArgument() throws Exception { + StringWriter writer = new StringWriter(); + writer.write("#define M1(var) var \n"); //$NON-NLS-1$ + writer.write("#define M2 1 \n"); //$NON-NLS-1$ + writer.write("int b= M2; \n"); //$NON-NLS-1$ + writer.write("int a= M1(M2); \n"); //$NON-NLS-1$ + String contents = writer.toString(); + IFile cpp= importFile("test.cpp", contents ); //$NON-NLS-1$ + + int offset1= contents.indexOf("M2"); //$NON-NLS-1$ + Change ch= getRefactorChanges(cpp, offset1, "xxx"); //$NON-NLS-1$ + assertTotalChanges(countOccurrences(contents, "M2"), ch); //$NON-NLS-1$ + } +} diff --git a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/refactoring/rename/RenameRegressionTests.java b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/refactoring/rename/RenameRegressionTests.java new file mode 100644 index 00000000000..584e3a8ecff --- /dev/null +++ b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/refactoring/rename/RenameRegressionTests.java @@ -0,0 +1,1263 @@ +/******************************************************************************* + * Copyright (c) 2004, 2007 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + * Wind River Systems Inc. - ported for new rename implementation + *******************************************************************************/ + +/* + * Created on Nov 10, 2004 + */ +package org.eclipse.cdt.ui.tests.refactoring.rename; + +import java.io.StringWriter; + +import junit.framework.*; + +import org.eclipse.cdt.core.dom.ast.IBinding; +import org.eclipse.cdt.core.tests.FailingTest; +import org.eclipse.core.resources.IFile; +import org.eclipse.ltk.core.refactoring.Change; +import org.eclipse.ltk.core.refactoring.RefactoringStatus; +import org.eclipse.ltk.core.refactoring.participants.RenameArguments; + +/** + * @author aniefer + */ +public class RenameRegressionTests extends RenameTests { + + public RenameRegressionTests() { + super(); + } + public RenameRegressionTests(String name) { + super(name); + } + + public static Test suite(){ + return suite( true ); + } + public static Test suite( boolean cleanup ) { + + TestSuite innerSuite= new TestSuite(RenameRegressionTests.class); + innerSuite.addTest( new FailingTest(new RenameRegressionTests("_testMethod_35_72726"),72726) ); //$NON-NLS-1$ + + TestSuite suite = new TestSuite("RenameRegressionTests"); //$NON-NLS-1$ + suite.addTest( innerSuite ); + suite.addTest( RenameVariableTests.suite(false)); + suite.addTest( RenameFunctionTests.suite(false)); + suite.addTest( RenameTypeTests.suite(false)); + suite.addTest( RenameMacroTests.suite(false)); + suite.addTest( RenameTemplatesTests.suite(false)); + + if( cleanup ) + suite.addTest( new RenameRegressionTests("cleanupProject") ); //$NON-NLS-1$ + + return suite; + } + + public void testSimpleRename() throws Exception { + StringWriter writer = new StringWriter(); + writer.write( "int boo; // boo \n" ); //$NON-NLS-1$ + writer.write( "#ifdef 0 \n" ); //$NON-NLS-1$ + writer.write( "boo \n" ); //$NON-NLS-1$ + writer.write( "#endif \n" ); //$NON-NLS-1$ + writer.write( "void f() { \n" ); //$NON-NLS-1$ + writer.write( " boo++; \n" ); //$NON-NLS-1$ + writer.write( "} \n" ); //$NON-NLS-1$ + + String contents = writer.toString(); + IFile file = importFile( "t.cpp", contents ); //$NON-NLS-1$ + Change changes = getRefactorChanges( file, contents.indexOf( "boo" ), "ooga" ); //$NON-NLS-1$ //$NON-NLS-2$ + + assertTotalChanges( 2, 1, 1, changes ); + assertChange( changes, file, contents.indexOf("boo"), 3, "ooga" ); //$NON-NLS-1$//$NON-NLS-2$ + assertChange( changes, file, contents.indexOf("boo++"), 3, "ooga" ); //$NON-NLS-1$//$NON-NLS-2$ + } + + public void testLocalVar() throws Exception { + StringWriter writer = new StringWriter(); + writer.write( "void f() { \n" ); //$NON-NLS-1$ + writer.write( " int boo; \n" ); //$NON-NLS-1$ + writer.write( " boo++; \n" ); //$NON-NLS-1$ + writer.write( " { \n" ); //$NON-NLS-1$ + writer.write( " int boo; \n" ); //$NON-NLS-1$ + writer.write( " boo++; \n" ); //$NON-NLS-1$ + writer.write( " } \n" ); //$NON-NLS-1$ + writer.write( " boo++; \n" ); //$NON-NLS-1$ + writer.write( "} \n" ); //$NON-NLS-1$ + + String contents = writer.toString(); + int offset= contents.indexOf("boo"); //$NON-NLS-1$ + IFile file = importFile( "t.cpp", contents ); //$NON-NLS-1$ + Change changes = getRefactorChanges( file, offset, "ooga" ); //$NON-NLS-1$ + + assertTotalChanges( 3, changes ); + assertChange( changes, file, offset, 3, "ooga" ); //$NON-NLS-1$ + offset= contents.indexOf("boo", offset+1); //$NON-NLS-1$ + assertChange( changes, file, offset, 3, "ooga" ); //$NON-NLS-1$ + offset= contents.lastIndexOf("boo"); //$NON-NLS-1$ + assertChange( changes, file, offset, 3, "ooga" ); //$NON-NLS-1$ + } + + public void testParameter() throws Exception { + StringWriter writer = new StringWriter(); + writer.write( "void f(int boo) { \n" ); //$NON-NLS-1$ + writer.write( " boo++; \n" ); //$NON-NLS-1$ + writer.write( " { \n" ); //$NON-NLS-1$ + writer.write( " int boo; \n" ); //$NON-NLS-1$ + writer.write( " boo++; \n" ); //$NON-NLS-1$ + writer.write( " } \n" ); //$NON-NLS-1$ + writer.write( " boo++; \n" ); //$NON-NLS-1$ + writer.write( "} \n" ); //$NON-NLS-1$ + + String contents = writer.toString(); + int offset= contents.indexOf("boo"); //$NON-NLS-1$ + IFile file = importFile( "t.cpp", contents ); //$NON-NLS-1$ + Change changes = getRefactorChanges( file, offset, "ooga" ); //$NON-NLS-1$ + + assertTotalChanges( 3, changes ); + assertChange( changes, file, offset, 3, "ooga" ); //$NON-NLS-1$ + offset= contents.indexOf("boo", offset+1); //$NON-NLS-1$ + assertChange( changes, file, offset, 3, "ooga" ); //$NON-NLS-1$ + offset= contents.lastIndexOf("boo"); //$NON-NLS-1$ + assertChange( changes, file, offset, 3, "ooga" ); //$NON-NLS-1$ + } + + public void testFileStaticVar() throws Exception { + StringWriter writer = new StringWriter(); + writer.write( "static int boo; \n" ); //$NON-NLS-1$ + writer.write( "void f() { \n" ); //$NON-NLS-1$ + writer.write( " boo++; \n" ); //$NON-NLS-1$ + writer.write( "} \n" ); //$NON-NLS-1$ + writer.write( "void g(int boo) { \n" ); //$NON-NLS-1$ + writer.write( " boo++; \n" ); //$NON-NLS-1$ + writer.write( "} \n" ); //$NON-NLS-1$ + + String contents = writer.toString(); + IFile file = importFile( "t.cpp", contents ); //$NON-NLS-1$ + importFile( "t2.cpp", contents ); //$NON-NLS-1$ + + int offset= contents.indexOf("boo"); //$NON-NLS-1$ + Change changes = getRefactorChanges( file, offset, "ooga" ); //$NON-NLS-1$ + + assertTotalChanges( 2, changes ); + assertChange( changes, file, offset, 3, "ooga" ); //$NON-NLS-1$ + offset= contents.indexOf("boo", offset+1); //$NON-NLS-1$ + assertChange( changes, file, offset, 3, "ooga" ); //$NON-NLS-1$ + } + + public void testClass_1() throws Exception { + StringWriter writer = new StringWriter(); + writer.write( "class Boo/*vp1*/{}; \n" ); //$NON-NLS-1$ + writer.write( "void f() { \n" ); //$NON-NLS-1$ + writer.write( " Boo a; \n" ); //$NON-NLS-1$ + writer.write( "} \n" ); //$NON-NLS-1$ + + String contents = writer.toString(); + IFile file = importFile( "t.cpp", contents ); //$NON-NLS-1$ + int offset= contents.indexOf( "Boo/*vp1*/" ); //$NON-NLS-1$ + Change changes = getRefactorChanges( file, offset, "Ooga" ); //$NON-NLS-1$ + + assertTotalChanges( 2, changes ); + assertChange( changes, file, contents.indexOf("Boo/*vp1*/"), 3, "Ooga" ); //$NON-NLS-1$//$NON-NLS-2$ + assertChange( changes, file, contents.indexOf("Boo a"), 3, "Ooga" ); //$NON-NLS-1$//$NON-NLS-2$ + } + public void testAttribute_2() throws Exception { + StringWriter writer = new StringWriter(); + writer.write( "class Boo{ \n" ); //$NON-NLS-1$ + writer.write( " int att1;//vp1,res1 \n" ); //$NON-NLS-1$ + writer.write( "}; \n" ); //$NON-NLS-1$ + writer.write( "void f() { \n" ); //$NON-NLS-1$ + writer.write( " Boo a; \n" ); //$NON-NLS-1$ + writer.write( " a.att1;//res2 \n" ); //$NON-NLS-1$ + writer.write( "} \n" ); //$NON-NLS-1$ + + String contents = writer.toString(); + IFile file = importFile( "t.cpp", contents ); //$NON-NLS-1$ + int offset = contents.indexOf( "att1;//vp1" ) ; //$NON-NLS-1$ + Change changes = getRefactorChanges(file, offset, "ooga" ); //$NON-NLS-1$ + + assertTotalChanges( 2, changes ); + assertChange( changes, file, contents.indexOf("att1;//vp1,res1"), 4, "ooga" ); //$NON-NLS-1$//$NON-NLS-2$ + assertChange( changes, file, contents.indexOf("att1;//res2"), 4, "ooga" ); //$NON-NLS-1$//$NON-NLS-2$ + } + public void testMethod_1() throws Exception { + StringWriter writer = new StringWriter(); + writer.write( "class Foo{ \n" ); //$NON-NLS-1$ + writer.write( "public: \n" ); //$NON-NLS-1$ + writer.write( " const void* method1(const char*); \n" ); //$NON-NLS-1$ + writer.write( "}; \n" ); //$NON-NLS-1$ + writer.write( "const void* Foo::method1(const char* x) { \n"); //$NON-NLS-1$ + writer.write( " return (void*) x; \n" ); //$NON-NLS-1$ + writer.write( "} \n" ); //$NON-NLS-1$ + writer.write( "void test() { \n" ); //$NON-NLS-1$ + writer.write( " Foo d; \n" ); //$NON-NLS-1$ + writer.write( " d.method1(\"hello\"); \n" ); //$NON-NLS-1$ + writer.write( "} \n" ); //$NON-NLS-1$ + String source = writer.toString(); + IFile cpp = importFile( "t.cpp", source ); //$NON-NLS-1$ + //vp1 const + int offset = source.indexOf( "method1" ); //$NON-NLS-1$ + Change changes = getRefactorChanges(cpp, offset, "m1" ); //$NON-NLS-1$ + assertTotalChanges( 3, changes ); + assertChange( changes, cpp, source.indexOf("method1"), 7, "m1" ); //$NON-NLS-1$//$NON-NLS-2$ + assertChange( changes, cpp, source.indexOf("method1(const"), 7, "m1" ); //$NON-NLS-1$//$NON-NLS-2$ + assertChange( changes, cpp, source.indexOf("method1(\"hello"), 7, "m1" ); //$NON-NLS-1$//$NON-NLS-2$ + } + + public void testMethod_3() throws Exception { + StringWriter writer = new StringWriter(); + writer.write( "class Boo{ \n" ); //$NON-NLS-1$ + writer.write( " int method1(){}//vp1,res1 \n" ); //$NON-NLS-1$ + writer.write( "}; \n" ); //$NON-NLS-1$ + writer.write( "void f() { \n" ); //$NON-NLS-1$ + writer.write( " Boo a; \n" ); //$NON-NLS-1$ + writer.write( " a.method1();//res2 \n" ); //$NON-NLS-1$ + writer.write( "} \n" ); //$NON-NLS-1$ + + String contents = writer.toString(); + IFile file = importFile( "t.cpp", contents ); //$NON-NLS-1$ + int offset = contents.indexOf( "method1(){}//vp1" ) ; //$NON-NLS-1$ + Change changes = getRefactorChanges(file, offset, "ooga" ); //$NON-NLS-1$ + + assertTotalChanges( 2, changes ); + assertChange( changes, file, contents.indexOf("method1(){}//vp1,res1"), 7, "ooga" ); //$NON-NLS-1$//$NON-NLS-2$ + assertChange( changes, file, contents.indexOf("method1();//res2"), 7, "ooga" ); //$NON-NLS-1$//$NON-NLS-2$ + } + + + public void testConstructor_26() throws Exception { + StringWriter writer = new StringWriter(); + writer.write( "class Boo{ \n" ); //$NON-NLS-1$ + writer.write( " Boo(){}//vp1,res1 \n" ); //$NON-NLS-1$ + writer.write( "}; \n" ); //$NON-NLS-1$ + writer.write( "void f() { \n" ); //$NON-NLS-1$ + writer.write( " Boo a = new Boo(); \n" ); //$NON-NLS-1$ + writer.write( "} \n" ); //$NON-NLS-1$ + + String contents = writer.toString(); + IFile file = importFile( "t.cpp", contents ); //$NON-NLS-1$ + int offset = contents.indexOf( "Boo(){}" ) ; //$NON-NLS-1$ + try { + getRefactorChanges(file, offset, "ooga" ); //$NON-NLS-1$ + } catch (AssertionFailedError e) { + assertTrue(e.getMessage().startsWith("Input check on ooga failed.")); //$NON-NLS-1$ + return; + } + fail ("An error should have occurred in the input check."); //$NON-NLS-1$ + } + //The constructor name is accepted, but the refactoring doesn't remove the return + //type and there is a compile error. Renaming to a constructor should be disabled. + //However, the UI does display the error in the preview panel. Defect 78769 states + //the error should be shown on the first page. The parser passes, but the UI could be + //better. + public void testConstructor_27() throws Exception { + StringWriter writer = new StringWriter(); + writer.write( "class Boo{ \n" ); //$NON-NLS-1$ + writer.write( " int foo(){}//vp1 \n" ); //$NON-NLS-1$ + writer.write( "}; \n" ); //$NON-NLS-1$ + writer.write( "void f() { \n" ); //$NON-NLS-1$ + writer.write( " Boo a; \n" ); //$NON-NLS-1$ + writer.write( " a.foo(); \n" ); //$NON-NLS-1$ + writer.write( "} \n" ); //$NON-NLS-1$ + + String contents = writer.toString(); + IFile file = importFile( "t.cpp", contents ); //$NON-NLS-1$ + int offset = contents.indexOf( "foo(){}" ) ; //$NON-NLS-1$ + try { + getRefactorChanges(file, offset, "Boo" ); //$NON-NLS-1$ + } catch (AssertionFailedError e) { + //test passes + assertTrue(e.getMessage().startsWith("Input check on Boo failed.")); //$NON-NLS-1$ + return; + } + fail ("An error should have occurred in the input check."); //$NON-NLS-1$ + } + public void testDestructor_28() throws Exception { + StringWriter writer = new StringWriter(); + writer.write( "class Boo{ \n" ); //$NON-NLS-1$ + writer.write( " ~Boo(){}//vp1 \n" ); //$NON-NLS-1$ + writer.write( "}; \n" ); //$NON-NLS-1$ + writer.write( "void f() { \n" ); //$NON-NLS-1$ + writer.write( " Boo a ; \n" ); //$NON-NLS-1$ + writer.write( " a.~Boo(); \n" ); //$NON-NLS-1$ + writer.write( "} \n" ); //$NON-NLS-1$ + + String contents = writer.toString(); + IFile file = importFile( "t.cpp", contents ); //$NON-NLS-1$ + int offset = contents.indexOf( "~Boo(){}" ) ; //$NON-NLS-1$ + try { + getRefactorChanges(file, offset, "ooga" ); //$NON-NLS-1$ + } catch (AssertionFailedError e) { + assertTrue(e.getMessage().startsWith("Input check on ooga failed.")); //$NON-NLS-1$ + return; + } + fail ("An error should have occurred in the input check."); //$NON-NLS-1$ + } + public void testDestructor_29_72612() throws Exception { + StringWriter writer = new StringWriter(); + writer.write( "class Boo{ \n" ); //$NON-NLS-1$ + writer.write( " int foo(){}//vp1 \n" ); //$NON-NLS-1$ + writer.write( "}; \n" ); //$NON-NLS-1$ + writer.write( "void f() { \n" ); //$NON-NLS-1$ + writer.write( " Boo a; \n" ); //$NON-NLS-1$ + writer.write( " a.foo(); \n" ); //$NON-NLS-1$ + writer.write( "} \n" ); //$NON-NLS-1$ + + String contents = writer.toString(); + IFile file = importFile( "t.cpp", contents ); //$NON-NLS-1$ + int offset = contents.indexOf( "foo(){}" ) ; //$NON-NLS-1$ + try { + getRefactorChanges(file, offset, "~Boo" ); //$NON-NLS-1$ + } catch (AssertionFailedError e) { + //test passes + assertTrue(e.getMessage().startsWith("Input check on ~Boo failed.")); //$NON-NLS-1$ + return; + } + fail ("An error should have occurred in the input check."); //$NON-NLS-1$ + } + public void testFunction_31() throws Exception { + StringWriter writer = new StringWriter(); + writer.write( "void foo(){} \n" ); //$NON-NLS-1$ + writer.write( "void foo/*vp1*/(int i){} \n" ); //$NON-NLS-1$ + writer.write( "class Foo{ \n" ); //$NON-NLS-1$ + writer.write( " int method1(){ \n" ); //$NON-NLS-1$ + writer.write( " foo(3); \n" ); //$NON-NLS-1$ + writer.write( " foo(); \n" ); //$NON-NLS-1$ + writer.write( " } \n" ); //$NON-NLS-1$ + writer.write( "}; \n" ); //$NON-NLS-1$ + + String contents = writer.toString(); + IFile file = importFile( "t.cpp", contents ); //$NON-NLS-1$ + int offset = contents.indexOf( "foo/*vp1*/" ) ; //$NON-NLS-1$ + Change changes = getRefactorChanges(file, offset, "ooga" ); //$NON-NLS-1$ + assertTotalChanges( 2, changes ); + assertChange( changes, file, contents.indexOf("foo/*vp1*/"), 3, "ooga" ); //$NON-NLS-1$//$NON-NLS-2$ + assertChange( changes, file, contents.indexOf("foo(3)"), 3, "ooga" ); //$NON-NLS-1$//$NON-NLS-2$ + + } + public void testMethod_32_72717() throws Exception { + StringWriter writer = new StringWriter(); + writer.write( "class Base { \n" ); //$NON-NLS-1$ + writer.write( " virtual void foo()=0; \n" ); //$NON-NLS-1$ + writer.write( "}; \n" ); //$NON-NLS-1$ + writer.write( "class Derived: public Base { \n" ); //$NON-NLS-1$ + writer.write( " virtual void foo(); \n" ); //$NON-NLS-1$ + writer.write( " void foo(char i); \n" ); //$NON-NLS-1$ + writer.write( " void moon/*vp1*/(int i); \n" ); //$NON-NLS-1$ + writer.write( "}; \n" ); //$NON-NLS-1$ + + String contents = writer.toString(); + IFile file = importFile( "t.cpp", contents ); //$NON-NLS-1$ + int offset = contents.indexOf( "moon/*vp1*/" ) ; //$NON-NLS-1$ + Change changes = getRefactorChanges(file, offset, "foo" ); //$NON-NLS-1$ + assertTotalChanges( 1, changes ); + assertChange( changes, file, contents.indexOf("moon/*vp1*/"), 4, "foo" ); //$NON-NLS-1$//$NON-NLS-2$ + RefactoringStatus status= checkConditions(file, offset, "foo"); //$NON-NLS-1$ + assertRefactoringWarning(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Overloading \n" + + "New element: foo \n" + + "Conflicting element type: Method"); //$NON-NLS-1$ + } + + public void testMethod_33_72605() throws Exception { + StringWriter writer = new StringWriter(); + writer.write( "class Foo { \n" ); //$NON-NLS-1$ + writer.write( " void aMethod/*vp1*/(int x=0); \n" ); //$NON-NLS-1$ + writer.write( "}; \n" ); //$NON-NLS-1$ + writer.write( "void Foo::aMethod(int x){} \n" ); //$NON-NLS-1$ + String contents = writer.toString(); + IFile file = importFile( "t.cpp", contents ); //$NON-NLS-1$ + int offset = contents.indexOf( "aMethod/*vp1*/" ) ; //$NON-NLS-1$ + Change changes = getRefactorChanges(file, offset, "ooga" ); //$NON-NLS-1$ + assertTotalChanges( 2, changes ); + assertChange( changes, file, contents.indexOf("aMethod/*vp1*/"), 7, "ooga" ); //$NON-NLS-1$//$NON-NLS-2$ + assertChange( changes, file, contents.indexOf("aMethod(int x)"), 7, "ooga" ); //$NON-NLS-1$//$NON-NLS-2$ + + } + + public void testMethod_33b_72605() throws Exception { + StringWriter writer = new StringWriter(); + writer.write( "class Foo { \n" ); //$NON-NLS-1$ + writer.write( " void aMethod/*vp1*/(int x=0); \n" ); //$NON-NLS-1$ + writer.write( "}; \n" ); //$NON-NLS-1$ + String header = writer.toString(); + IFile hFile= importFile("t.hh", header); //$NON-NLS-1$ + writer= new StringWriter(); + writer.write( "#include \"t.hh\" \n" ); //$NON-NLS-1$ + writer.write( "void Foo::aMethod(int x){} \n" ); //$NON-NLS-1$ + String source = writer.toString(); + IFile cppfile = importFile( "t.cpp", source ); //$NON-NLS-1$ + + int hoffset = header.indexOf( "aMethod" ) ; //$NON-NLS-1$ + int cppoffset = source.indexOf( "aMethod" ) ; //$NON-NLS-1$ + + Change changes = getRefactorChanges(hFile, hoffset, "ooga" ); //$NON-NLS-1$ + assertTotalChanges( 2, changes ); + assertChange( changes, hFile, hoffset, 7, "ooga" ); //$NON-NLS-1$ + assertChange( changes, cppfile, cppoffset, 7, "ooga" ); //$NON-NLS-1$ + + changes = getRefactorChanges(cppfile, cppoffset, "ooga" ); //$NON-NLS-1$ + assertTotalChanges( 2, changes ); + assertChange( changes, hFile, hoffset, 7, "ooga" ); //$NON-NLS-1$ + assertChange( changes, cppfile, cppoffset, 7, "ooga" ); //$NON-NLS-1$ + } + + public void testMethod_34() throws Exception { + StringWriter writer = new StringWriter(); + writer.write( "class Base{ \n" ); //$NON-NLS-1$ + writer.write( " virtual void v/*vp1*/()=0; \n" ); //$NON-NLS-1$ + writer.write( "}; \n" ); //$NON-NLS-1$ + writer.write( "class Derived: Base { \n" ); //$NON-NLS-1$ + writer.write( " void v(){}; \n" ); //$NON-NLS-1$ + writer.write( "}; \n" ); //$NON-NLS-1$ + String contents = writer.toString(); + IFile file = importFile( "t.cpp", contents ); //$NON-NLS-1$ + int offset = contents.indexOf( "v/*vp1*/" ) ; //$NON-NLS-1$ + Change changes = getRefactorChanges(file, offset, "ooga" ); //$NON-NLS-1$ + //dervied method is not renamed; only a warning to rename derived or base class methods + assertTotalChanges( 1, changes ); + assertChange( changes, file, contents.indexOf("v/*vp1*/"), 1, "ooga" ); //$NON-NLS-1$//$NON-NLS-2$ + + } + // defect is input for new name is not allowed + public void _testMethod_35_72726() throws Exception { + StringWriter writer = new StringWriter(); + writer.write( "class Foo{ \n" ); //$NON-NLS-1$ + writer.write( " Foo& operator *=/*vp1*/(const Foo &rhs);\n" ); //$NON-NLS-1$ + writer.write( " Foo& operator==/*vp2*/(const Foo &rhs);\n" ); //$NON-NLS-1$ + writer.write( "}; \n" ); //$NON-NLS-1$ + writer.write( "Foo& Foo::operator *=(const Foo &rhs){ \n" ); //$NON-NLS-1$ + writer.write( " return *this; \n" ); //$NON-NLS-1$ + writer.write( "}; \n" ); //$NON-NLS-1$ + writer.write( "Foo& Foo::operator==(const Foo &rhs){ \n" ); //$NON-NLS-1$ + writer.write( " return *this; \n" ); //$NON-NLS-1$ + writer.write( "}; \n" ); //$NON-NLS-1$ + String contents = writer.toString(); + IFile file = importFile( "t.cpp", contents ); //$NON-NLS-1$ + //vp1 with space + int offset = contents.indexOf( "operator *=/*vp1*/" ) ; //$NON-NLS-1$ + Change changes = getRefactorChanges(file, offset, "operator +=" ); //$NON-NLS-1$ + assertTotalChanges( 2, changes ); + assertChange( changes, file, contents.indexOf("operator *=/*vp1*/"), 11, "operator +=" ); //$NON-NLS-1$//$NON-NLS-2$ + assertChange( changes, file, contents.indexOf("operator *=(const"), 11, "operator +=" ); //$NON-NLS-1$//$NON-NLS-2$ + //vp2 without space + offset = contents.indexOf( "operator==/*vp2*/" ) ; //$NON-NLS-1$ + changes = getRefactorChanges(file, offset, "operator=" ); //$NON-NLS-1$ + assertTotalChanges( 2, changes ); + assertChange( changes, file, contents.indexOf("operator==/*vp2*/"), 11, "operator=" ); //$NON-NLS-1$//$NON-NLS-2$ + assertChange( changes, file, contents.indexOf("operator==(const"), 11, "operator=" ); //$NON-NLS-1$//$NON-NLS-2$ + + } + public void testMethod_39() throws Exception { + StringWriter writer = new StringWriter(); + writer.write( "class Foo{ \n" ); //$NON-NLS-1$ + writer.write( " const void* method1(const char*); \n" ); //$NON-NLS-1$ + writer.write( " const int method2(int j); \n" ); //$NON-NLS-1$ + writer.write( "}; \n" ); //$NON-NLS-1$ + String header = writer.toString(); + IFile h = importFile( "t.hh", header ); //$NON-NLS-1$ + + writer = new StringWriter(); + writer.write( "#include \"t.hh\" \n" ); //$NON-NLS-1$ + writer.write( "const void* Foo::method1(const char* x){return (void*) x;} \n" ); //$NON-NLS-1$ + writer.write( "const int Foo::method2(int){return 5;} \n" ); //$NON-NLS-1$ + writer.write( "void test() { \n" ); //$NON-NLS-1$ + writer.write( " Foo d; \n" ); //$NON-NLS-1$ + writer.write( " d.method1(\"hello\"); \n" ); //$NON-NLS-1$ + writer.write( " int i =d.method2(3); \n" ); //$NON-NLS-1$ + writer.write( "} \n" ); //$NON-NLS-1$ + String source = writer.toString(); + IFile cpp = importFile( "t.cpp", source ); //$NON-NLS-1$ + //vp1 const + int offset = header.indexOf( "method1" ); //$NON-NLS-1$ + Change changes = getRefactorChanges(h, offset, "m1" ); //$NON-NLS-1$ + assertTotalChanges( 3, changes ); + assertChange( changes, h, header.indexOf("method1"), 7, "m1" ); //$NON-NLS-1$//$NON-NLS-2$ + assertChange( changes, cpp, source.indexOf("method1(const"), 7, "m1" ); //$NON-NLS-1$//$NON-NLS-2$ + assertChange( changes, cpp, source.indexOf("method1(\"hello"), 7, "m1" ); //$NON-NLS-1$//$NON-NLS-2$ + //vp2 const in definition with :: + offset = source.indexOf( "method2(int" ); //$NON-NLS-1$ + changes = getRefactorChanges(cpp, offset, "m2" ); //$NON-NLS-1$ + assertTotalChanges( 3, changes ); + assertChange( changes, h, header.indexOf("method2"), 7, "m2" ); //$NON-NLS-1$//$NON-NLS-2$ + assertChange( changes, cpp, source.indexOf("method2(int"), 7, "m2" ); //$NON-NLS-1$//$NON-NLS-2$ + assertChange( changes, cpp, source.indexOf("method2(3"), 7, "m2" ); //$NON-NLS-1$//$NON-NLS-2$ + + } + public void testMethod_40() throws Exception { + StringWriter writer = new StringWriter(); + writer.write( "class Foo{ \n" ); //$NON-NLS-1$ + writer.write( " static int method1/*vp1*/(const char* x); \n" ); //$NON-NLS-1$ + writer.write( " static int method2/*vp2*/(int); \n" ); //$NON-NLS-1$ + writer.write( "}; \n" ); //$NON-NLS-1$ + String header = writer.toString(); + IFile h = importFile( "t.hh", header ); //$NON-NLS-1$ + + writer = new StringWriter(); + writer.write( "#include \"t.hh\" \n" ); //$NON-NLS-1$ + writer.write( "static int Foo::method1(const char* x){return 5;} \n" ); //$NON-NLS-1$ + writer.write( "static int Foo::method2(int x){return (2);}; \n" ); //$NON-NLS-1$ + writer.write( "void test() { \n" ); //$NON-NLS-1$ + writer.write( " Foo::method1(\"hello\"); \n" ); //$NON-NLS-1$ + writer.write( " int i =Foo::method2(3); \n" ); //$NON-NLS-1$ + writer.write( "} \n" ); //$NON-NLS-1$ + String source = writer.toString(); + IFile cpp = importFile( "t.cpp", source ); //$NON-NLS-1$ + //vp1 static method declaration + int offset = header.indexOf( "method1/*vp1*/" ); //$NON-NLS-1$ + Change changes = getRefactorChanges(h, offset, "m1" ); //$NON-NLS-1$ + assertTotalChanges( 3, changes ); + assertChange( changes, h, header.indexOf("method1/*vp1*/"), 7, "m1" ); //$NON-NLS-1$//$NON-NLS-2$ + assertChange( changes, cpp, source.indexOf("method1(const"), 7, "m1" ); //$NON-NLS-1$//$NON-NLS-2$ + assertChange( changes, cpp, source.indexOf("method1(\"hello"), 7, "m1" ); //$NON-NLS-1$//$NON-NLS-2$ + //vp2 static method definition + offset = source.indexOf( "Foo::method2" )+5; //$NON-NLS-1$ + changes = getRefactorChanges(cpp, offset, "m2" ); //$NON-NLS-1$ + assertTotalChanges( 3, changes ); + assertChange( changes, h, header.indexOf("method2/*vp2*/"), 7, "m2" ); //$NON-NLS-1$//$NON-NLS-2$ + assertChange( changes, cpp, source.indexOf("method2(int x"), 7, "m2" ); //$NON-NLS-1$//$NON-NLS-2$ + assertChange( changes, cpp, source.indexOf("method2(3"), 7, "m2" ); //$NON-NLS-1$//$NON-NLS-2$ + + } + + public void testMethod_41() throws Exception { + StringWriter writer = new StringWriter(); + writer.write( "class Foo{ \n" ); //$NON-NLS-1$ + writer.write( "public: \n" ); //$NON-NLS-1$ + writer.write( " volatile int method1/*vp1*/(int); \n" ); //$NON-NLS-1$ + writer.write( "private: \n" ); //$NON-NLS-1$ + writer.write( " int b; \n" ); //$NON-NLS-1$ + writer.write( "}; \n" ); //$NON-NLS-1$ + String header = writer.toString(); + IFile h = importFile( "t.hh", header ); //$NON-NLS-1$ + + writer = new StringWriter(); + writer.write( "#include \"t.hh\" \n" ); //$NON-NLS-1$ + writer.write( "volatile int Foo::method1(int x){return (2);}; \n" ); //$NON-NLS-1$ + writer.write( "void test() { \n" ); //$NON-NLS-1$ + writer.write( " Foo d; \n" ); //$NON-NLS-1$ + writer.write( " int i =d.method1(1); \n" ); //$NON-NLS-1$ + writer.write( "} \n" ); //$NON-NLS-1$ + String source = writer.toString(); + IFile cpp = importFile( "t.cpp", source ); //$NON-NLS-1$ + //vp1 volatile + int offset = header.indexOf( "method1/*vp1*/" ) ; //$NON-NLS-1$ + Change changes = getRefactorChanges(h, offset, "m1" ); //$NON-NLS-1$ + assertTotalChanges( 3, changes ); + assertChange( changes, h, header.indexOf("method1/*vp1*/"), 7, "m1" ); //$NON-NLS-1$//$NON-NLS-2$ + assertChange( changes, cpp, source.indexOf("method1(int x"), 7, "m1" ); //$NON-NLS-1$//$NON-NLS-2$ + assertChange( changes, cpp, source.indexOf("method1(1"), 7, "m1" ); //$NON-NLS-1$//$NON-NLS-2$ + + } + public void testMethod_43() throws Exception { + StringWriter writer = new StringWriter(); + writer.write( "class Foo{ \n" ); //$NON-NLS-1$ + writer.write( "public: \n" ); //$NON-NLS-1$ + writer.write( " inline void method1/*vp1*/(int i) {b=i;} \n" ); //$NON-NLS-1$ + writer.write( "private: \n" ); //$NON-NLS-1$ + writer.write( " int b; \n" ); //$NON-NLS-1$ + writer.write( "}; \n" ); //$NON-NLS-1$ + String header = writer.toString(); + IFile h = importFile( "t.hh", header ); //$NON-NLS-1$ + + writer = new StringWriter(); + writer.write( "#include \"t.hh\" \n" ); //$NON-NLS-1$ + writer.write( "void test() { \n" ); //$NON-NLS-1$ + writer.write( " Foo d; \n" ); //$NON-NLS-1$ + writer.write( " d->method1(1); \n" ); //$NON-NLS-1$ + writer.write( "} \n" ); //$NON-NLS-1$ + String source = writer.toString(); + IFile cpp = importFile( "t.cpp", source ); //$NON-NLS-1$ + //vp1 inline + int offset = header.indexOf( "method1/*vp1*/" ) ; //$NON-NLS-1$ + Change changes = getRefactorChanges(h, offset, "m1" ); //$NON-NLS-1$ + assertTotalChanges( 2, changes ); + assertChange( changes, h, header.indexOf("method1/*vp1*/"), 7, "m1" ); //$NON-NLS-1$//$NON-NLS-2$ + assertChange( changes, cpp, source.indexOf("method1(1"), 7, "m1" ); //$NON-NLS-1$//$NON-NLS-2$ + + } + public void testMethod_44() throws Exception { + StringWriter writer = new StringWriter(); + writer.write( "class Base{ \n" ); //$NON-NLS-1$ + writer.write( " virtual void v(); \n" ); //$NON-NLS-1$ + writer.write( " int i; \n" ); //$NON-NLS-1$ + writer.write( "}; \n" ); //$NON-NLS-1$ + writer.write( "void Base::v(){} \n" ); //$NON-NLS-1$ + writer.write( "class Derived: Base { \n" ); //$NON-NLS-1$ + writer.write( " virtual void v/*vp1*/(){}//explicitly virtual \n" ); //$NON-NLS-1$ + writer.write( "}; \n" ); //$NON-NLS-1$ + writer.write( "class Derived2: Derived {\n" ); //$NON-NLS-1$ + writer.write( " void v(){i++;} \n" ); //$NON-NLS-1$ + writer.write( "}; \n" ); //$NON-NLS-1$ + String contents = writer.toString(); + IFile file = importFile( "t.cpp", contents ); //$NON-NLS-1$ + //vp1 implicit virtual method + int offset = contents.indexOf( "v/*vp1*/" ) ; //$NON-NLS-1$ + String[] messages= getRefactorMessages( file, offset, "v2" ); //$NON-NLS-1$ + assertEquals(1, messages.length); + assertEquals("Renaming a virtual method. Consider renaming the base and derived class methods (if any).", messages[0] ); //$NON-NLS-1$ + +} + public void testMethod_45() throws Exception { + StringWriter writer = new StringWriter(); + writer.write( "class Base{ \n" ); //$NON-NLS-1$ + writer.write( " virtual void v(); \n" ); //$NON-NLS-1$ + writer.write( " int i; \n" ); //$NON-NLS-1$ + writer.write( "}; \n" ); //$NON-NLS-1$ + writer.write( "void Base::v(){} \n" ); //$NON-NLS-1$ + writer.write( "class Derived: Base { \n" ); //$NON-NLS-1$ + writer.write( " void v/*vp1*/(){}//implicitly virtual \n" ); //$NON-NLS-1$ + writer.write( "}; \n" ); //$NON-NLS-1$ + writer.write( "class Derived2: Derived {\n" ); //$NON-NLS-1$ + writer.write( " void v(){i++;} \n" ); //$NON-NLS-1$ + writer.write( "}; \n" ); //$NON-NLS-1$ + String contents = writer.toString(); + IFile file = importFile( "t.cpp", contents ); //$NON-NLS-1$ + //vp1 implicit virtual method + int offset = contents.indexOf( "v/*vp1*/" ) ; //$NON-NLS-1$ + String[] messages= getRefactorMessages( file, offset, "v2" ); //$NON-NLS-1$ + assertEquals(1, messages.length); + assertEquals("Renaming a virtual method. Consider renaming the base and derived class methods (if any).", messages[0] ); //$NON-NLS-1$ + + + } + public void testStruct_46() throws Exception { + StringWriter writer = new StringWriter(); + writer.write( "struct st1/*vp1*/{}; \n" ); //$NON-NLS-1$ + writer.write( "class c1/*vp1*/{ \n" ); //$NON-NLS-1$ + writer.write( " public: struct st2/*vp2*/{} s; \n" ); //$NON-NLS-1$ + writer.write( "}; \n" ); //$NON-NLS-1$ + writer.write( "namespace N{ \n" ); //$NON-NLS-1$ + writer.write( " struct st3/*vp3*/{}; \n" ); //$NON-NLS-1$ + writer.write( " class c2/*vp1*/{ \n" ); //$NON-NLS-1$ + writer.write( " st1 s; \n" ); //$NON-NLS-1$ + writer.write( " st3 ss; \n" ); //$NON-NLS-1$ + writer.write( " c2() { \n" ); //$NON-NLS-1$ + writer.write( " c1::st2 s; \n" ); //$NON-NLS-1$ + writer.write( " } \n" ); //$NON-NLS-1$ + writer.write( " }; \n" ); //$NON-NLS-1$ + writer.write( "} \n" ); //$NON-NLS-1$ + + String contents = writer.toString(); + IFile file = importFile( "t.cpp", contents ); //$NON-NLS-1$ + //vp1 global declaration + int offset = contents.indexOf( "st1/*vp1*/" ) ; //$NON-NLS-1$ + Change changes = getRefactorChanges(file, offset, "Ooga1" ); //$NON-NLS-1$ + assertTotalChanges( 2, changes ); + assertChange( changes, file, contents.indexOf("st1/*vp1*/"), 3, "Ooga1" ); //$NON-NLS-1$//$NON-NLS-2$ + assertChange( changes, file, contents.indexOf("st1 s"), 3, "Ooga1" ); //$NON-NLS-1$//$NON-NLS-2$ + //vp2 Declared in class + offset = contents.indexOf( "st2/*vp2*/" ) ; //$NON-NLS-1$ + changes = getRefactorChanges(file, offset, "Ooga2" ); //$NON-NLS-1$ + assertTotalChanges( 2, changes ); + assertChange( changes, file, contents.indexOf("st2/*vp2*/"), 3, "Ooga2" ); //$NON-NLS-1$//$NON-NLS-2$ + assertChange( changes, file, contents.indexOf("st2 s"), 3, "Ooga2" ); //$NON-NLS-1$//$NON-NLS-2$ + //vp3 Declared in namespace + offset = contents.indexOf( "st3/*vp3*/" ) ; //$NON-NLS-1$ + changes = getRefactorChanges(file, offset, "Ooga3" ); //$NON-NLS-1$ + assertTotalChanges( 2, changes ); + assertChange( changes, file, contents.indexOf("st3/*vp3*/"), 3, "Ooga3" ); //$NON-NLS-1$//$NON-NLS-2$ + assertChange( changes, file, contents.indexOf("st3 ss"), 3, "Ooga3" ); //$NON-NLS-1$//$NON-NLS-2$ + } + public void testUnion_47() throws Exception { + StringWriter writer = new StringWriter(); + writer.write( "union st1/*vp1*/{}; \n" ); //$NON-NLS-1$ + writer.write( "class c1/*vp1*/{ \n" ); //$NON-NLS-1$ + writer.write( " public: union st2/*vp2*/{} s; \n" ); //$NON-NLS-1$ + writer.write( "}; \n" ); //$NON-NLS-1$ + writer.write( "namespace N{ \n" ); //$NON-NLS-1$ + writer.write( " union st3/*vp3*/{}; \n" ); //$NON-NLS-1$ + writer.write( " class c2/*vp1*/{ \n" ); //$NON-NLS-1$ + writer.write( " st1 s; \n" ); //$NON-NLS-1$ + writer.write( " st3 ss; \n" ); //$NON-NLS-1$ + writer.write( " c2() { \n" ); //$NON-NLS-1$ + writer.write( " c1::st2 s; \n" ); //$NON-NLS-1$ + writer.write( " } \n" ); //$NON-NLS-1$ + writer.write( " }; \n" ); //$NON-NLS-1$ + writer.write( "} \n" ); //$NON-NLS-1$ + + String contents = writer.toString(); + IFile file = importFile( "t.cpp", contents ); //$NON-NLS-1$ + //vp1 global declaration + int offset = contents.indexOf( "st1/*vp1*/" ) ; //$NON-NLS-1$ + Change changes = getRefactorChanges(file, offset, "Ooga1" ); //$NON-NLS-1$ + assertTotalChanges( 2, changes ); + assertChange( changes, file, contents.indexOf("st1/*vp1*/"), 3, "Ooga1" ); //$NON-NLS-1$//$NON-NLS-2$ + assertChange( changes, file, contents.indexOf("st1 s"), 3, "Ooga1" ); //$NON-NLS-1$//$NON-NLS-2$ + //vp2 Declared in class + offset = contents.indexOf( "st2/*vp2*/" ) ; //$NON-NLS-1$ + changes = getRefactorChanges(file, offset, "Ooga2" ); //$NON-NLS-1$ + assertTotalChanges( 2, changes ); + assertChange( changes, file, contents.indexOf("st2/*vp2*/"), 3, "Ooga2" ); //$NON-NLS-1$//$NON-NLS-2$ + assertChange( changes, file, contents.indexOf("st2 s"), 3, "Ooga2" ); //$NON-NLS-1$//$NON-NLS-2$ + //vp3 Declared in namespace + offset = contents.indexOf( "st3/*vp3*/" ) ; //$NON-NLS-1$ + changes = getRefactorChanges(file, offset, "Ooga3" ); //$NON-NLS-1$ + assertTotalChanges( 2, changes ); + assertChange( changes, file, contents.indexOf("st3/*vp3*/"), 3, "Ooga3" ); //$NON-NLS-1$//$NON-NLS-2$ + assertChange( changes, file, contents.indexOf("st3 ss"), 3, "Ooga3" ); //$NON-NLS-1$//$NON-NLS-2$ +} + public void testEnumeration_48() throws Exception { + StringWriter writer = new StringWriter(); + writer.write( "enum e1/*vp1*/{E0}; \n" ); //$NON-NLS-1$ + writer.write( "class c1 { \n" ); //$NON-NLS-1$ + writer.write( " public: enum e2/*vp2*/{E1} s; \n" ); //$NON-NLS-1$ + writer.write( "}; \n" ); //$NON-NLS-1$ + writer.write( "namespace N{ \n" ); //$NON-NLS-1$ + writer.write( " enum e3/*vp3*/{}; \n" ); //$NON-NLS-1$ + writer.write( " class c2/*vp1*/{ \n" ); //$NON-NLS-1$ + writer.write( " e1 s; \n" ); //$NON-NLS-1$ + writer.write( " e3 ss; \n" ); //$NON-NLS-1$ + writer.write( " c2() { \n" ); //$NON-NLS-1$ + writer.write( " c1::e2 s; \n" ); //$NON-NLS-1$ + writer.write( " } \n" ); //$NON-NLS-1$ + writer.write( " }; \n" ); //$NON-NLS-1$ + writer.write( "} \n" ); //$NON-NLS-1$ + + String contents = writer.toString(); + IFile file = importFile( "t.cpp", contents ); //$NON-NLS-1$ + //vp1 global declaration + int offset = contents.indexOf( "e1/*vp1*/" ) ; //$NON-NLS-1$ + Change changes = getRefactorChanges(file, offset, "Ooga1" ); //$NON-NLS-1$ + assertTotalChanges( 2, changes ); + assertChange( changes, file, contents.indexOf("e1/*vp1*/"), 2, "Ooga1" ); //$NON-NLS-1$//$NON-NLS-2$ + assertChange( changes, file, contents.indexOf("e1 s"), 2, "Ooga1" ); //$NON-NLS-1$//$NON-NLS-2$ + //vp2 Declared in class + offset = contents.indexOf( "e2/*vp2*/" ) ; //$NON-NLS-1$ + changes = getRefactorChanges(file, offset, "Ooga2" ); //$NON-NLS-1$ + assertTotalChanges( 2, changes ); + assertChange( changes, file, contents.indexOf("e2/*vp2*/"), 2, "Ooga2" ); //$NON-NLS-1$//$NON-NLS-2$ + assertChange( changes, file, contents.indexOf("e2 s"), 2, "Ooga2" ); //$NON-NLS-1$//$NON-NLS-2$ + //vp3 Declared in namespace + offset = contents.indexOf( "e3/*vp3*/" ) ; //$NON-NLS-1$ + changes = getRefactorChanges(file, offset, "Ooga3" ); //$NON-NLS-1$ + assertTotalChanges( 2, changes ); + assertChange( changes, file, contents.indexOf("e3/*vp3*/"), 2, "Ooga3" ); //$NON-NLS-1$//$NON-NLS-2$ + assertChange( changes, file, contents.indexOf("e3 ss"), 2, "Ooga3" ); //$NON-NLS-1$//$NON-NLS-2$ + } + public void testTemplate_49_72626() throws Exception { + StringWriter writer = new StringWriter(); + writer.write( "template \n" ); //$NON-NLS-1$ + writer.write( "class Array/*vp1*/ { \n" ); //$NON-NLS-1$ + writer.write( " public: Array(){ \n" ); //$NON-NLS-1$ + writer.write( " a=new Type[10]; \n" ); //$NON-NLS-1$ + writer.write( " } \n" ); //$NON-NLS-1$ + writer.write( " virtual Type& operator[](int i){return a[i];} \n" ); //$NON-NLS-1$ + writer.write( " protected: Type *a; \n" ); //$NON-NLS-1$ + writer.write( "}; \n" ); //$NON-NLS-1$ + writer.write( "void f(){ \n" ); //$NON-NLS-1$ + writer.write( " Array a; \n" ); //$NON-NLS-1$ + writer.write( "} \n" ); //$NON-NLS-1$ + + String contents = writer.toString(); + IFile file = importFile( "t.cpp", contents ); //$NON-NLS-1$ + int offset = contents.indexOf( "Array" ) ; //$NON-NLS-1$ + Change changes= getRefactorChanges(file, offset, "Arr2" ); //$NON-NLS-1$ + assertTotalChanges( 3, changes ); + assertChange( changes, file, offset, 5, "Arr2" ); //$NON-NLS-1$ + assertChange( changes, file, offset=contents.indexOf("Array", offset+1), 5, "Arr2" ); //$NON-NLS-1$//$NON-NLS-2$ + assertChange( changes, file, offset=contents.indexOf("Array", offset+1), 5, "Arr2" ); //$NON-NLS-1$//$NON-NLS-2$ + } + public void testClass_52() throws Exception { + StringWriter writer = new StringWriter(); + writer.write( "namespace N1 { \n" ); //$NON-NLS-1$ + writer.write( "class Boo{}; \n" ); //$NON-NLS-1$ + writer.write( "} \n" ); //$NON-NLS-1$ + writer.write( "namespace N2 { \n" ); //$NON-NLS-1$ + writer.write( "class Boo/*vp1*/{}; \n" ); //$NON-NLS-1$ + writer.write( "} \n" ); //$NON-NLS-1$ + writer.write( "void f() { \n" ); //$NON-NLS-1$ + writer.write( " N1::Boo c1; \n" ); //$NON-NLS-1$ + writer.write( " N2::Boo c2; \n" ); //$NON-NLS-1$ + writer.write( "} \n" ); //$NON-NLS-1$ + + String contents = writer.toString(); + IFile file = importFile( "t.cpp", contents ); //$NON-NLS-1$ + int offset = contents.indexOf( "Boo/*vp1*/" ) ; //$NON-NLS-1$ + Change changes = getRefactorChanges(file, offset, "Ooga" ); //$NON-NLS-1$ + + assertTotalChanges( 2, changes ); + assertChange( changes, file, contents.indexOf("Boo/*vp1*/"), 3, "Ooga" ); //$NON-NLS-1$//$NON-NLS-2$ + assertChange( changes, file, contents.indexOf("Boo c2"), 3, "Ooga" ); //$NON-NLS-1$//$NON-NLS-2$ + } + public void testClass_53() throws Exception { + StringWriter writer = new StringWriter(); + writer.write( "class Foo/*vp1*/ {//ren1 \n" ); //$NON-NLS-1$ + writer.write( " Foo();//ren2 \n" ); //$NON-NLS-1$ + writer.write( " virtual ~Foo();//ren3 \n" ); //$NON-NLS-1$ + writer.write( "}; \n" ); //$NON-NLS-1$ + writer.write( "Foo::Foo() {}//ren4,5 \n" ); //$NON-NLS-1$ + writer.write( "Foo::~Foo() {}//ren6,7 \n" ); //$NON-NLS-1$ + writer.write( "void f() { \n" ); //$NON-NLS-1$ + writer.write( " Foo *f=new Foo();//ren8,9 \n" ); //$NON-NLS-1$ + writer.write( " f->~Foo();//ren10 \n" ); //$NON-NLS-1$ + writer.write( "} \n" ); //$NON-NLS-1$ + + String contents = writer.toString(); + IFile file = importFile( "t.cpp", contents ); //$NON-NLS-1$ + int offset = contents.indexOf( "Foo/*vp1*/" ) ; //$NON-NLS-1$ + Change changes = getRefactorChanges(file, offset, "Ooga" ); //$NON-NLS-1$ + + assertTotalChanges( 10, changes ); + assertChange( changes, file, contents.indexOf("Foo/*vp1*/"), 3, "Ooga" ); //$NON-NLS-1$//$NON-NLS-2$ + assertChange( changes, file, contents.indexOf("Foo();//ren2"), 3, "Ooga" ); //$NON-NLS-1$//$NON-NLS-2$ + assertChange( changes, file, contents.indexOf("Foo();//ren3"), 3, "Ooga" ); //$NON-NLS-1$//$NON-NLS-2$ + assertChange( changes, file, contents.indexOf("Foo::Foo() {}//ren4,5"), 3, "Ooga" ); //$NON-NLS-1$//$NON-NLS-2$ + assertChange( changes, file, contents.indexOf("Foo() {}//ren4,5"), 3, "Ooga" ); //$NON-NLS-1$//$NON-NLS-2$ + assertChange( changes, file, contents.indexOf("Foo::~Foo() {}//ren6,7"), 3, "Ooga" ); //$NON-NLS-1$//$NON-NLS-2$ + assertChange( changes, file, contents.indexOf("Foo() {}//ren6,7"), 3, "Ooga" ); //$NON-NLS-1$//$NON-NLS-2$ + assertChange( changes, file, contents.indexOf("Foo *f=new Foo();//ren8,9"), 3, "Ooga" ); //$NON-NLS-1$//$NON-NLS-2$ + assertChange( changes, file, contents.indexOf("Foo();//ren8,9"), 3, "Ooga" ); //$NON-NLS-1$//$NON-NLS-2$ + assertChange( changes, file, contents.indexOf("Foo();//ren10"), 3, "Ooga" ); //$NON-NLS-1$//$NON-NLS-2$ + } + public void testAttribute_54() throws Exception { + StringWriter writer = new StringWriter(); + writer.write( "class Boo{ \n" ); //$NON-NLS-1$ + writer.write( " static int att;//vp1,rn1 \n" ); //$NON-NLS-1$ + writer.write( "}; \n" ); //$NON-NLS-1$ + writer.write( "void f() { \n" ); //$NON-NLS-1$ + writer.write( " Boo a; \n" ); //$NON-NLS-1$ + writer.write( " a.att;//rn2 \n" ); //$NON-NLS-1$ + writer.write( " Boo::att;//rn3 \n" ); //$NON-NLS-1$ + writer.write( "} \n" ); //$NON-NLS-1$ + + String contents = writer.toString(); + IFile file = importFile( "t.cpp", contents ); //$NON-NLS-1$ + int offset = contents.indexOf( "att;//vp1" ) ; //$NON-NLS-1$ + Change changes = getRefactorChanges(file, offset, "ooga" ); //$NON-NLS-1$ + + assertTotalChanges( 3, changes ); + assertChange( changes, file, contents.indexOf("att;//vp1"), 3, "ooga" ); //$NON-NLS-1$//$NON-NLS-2$ + assertChange( changes, file, contents.indexOf("att;//rn2"), 3, "ooga" ); //$NON-NLS-1$//$NON-NLS-2$ + assertChange( changes, file, contents.indexOf("att;//rn3"), 3, "ooga" ); //$NON-NLS-1$//$NON-NLS-2$ + } + public void testClass_55() throws Exception { + StringWriter writer = new StringWriter(); + writer.write( "class Foo{ \n" ); //$NON-NLS-1$ + writer.write( " class Hoo{//vp1 \n" ); //$NON-NLS-1$ + writer.write( " public: Hoo(); \n" ); //$NON-NLS-1$ + writer.write( " }; \n" ); //$NON-NLS-1$ + writer.write( " Foo(){ \n" ); //$NON-NLS-1$ + writer.write( " Foo::Hoo h; \n" ); //$NON-NLS-1$ + writer.write( " } \n" ); //$NON-NLS-1$ + writer.write( "}; \n" ); //$NON-NLS-1$ + writer.write( "Foo::Hoo::Hoo(){} \n" ); //$NON-NLS-1$ + + String contents = writer.toString(); + IFile file = importFile( "t.cpp", contents ); //$NON-NLS-1$ + int offset = contents.indexOf( "Hoo{" ) ; //$NON-NLS-1$ + Change changes = getRefactorChanges(file, offset, "ooga" ); //$NON-NLS-1$ + + assertTotalChanges( 5, changes ); + assertChange( changes, file, contents.indexOf("Hoo{//vp1"), 3, "ooga" ); //$NON-NLS-1$//$NON-NLS-2$ + assertChange( changes, file, contents.indexOf("Hoo();"), 3, "ooga" ); //$NON-NLS-1$//$NON-NLS-2$ + assertChange( changes, file, contents.indexOf("Hoo h;"), 3, "ooga" ); //$NON-NLS-1$//$NON-NLS-2$ + assertChange( changes, file, contents.indexOf("Hoo::Hoo(){}"), 3, "ooga" ); //$NON-NLS-1$//$NON-NLS-2$ + assertChange( changes, file, contents.indexOf("Hoo(){}"), 3, "ooga" ); //$NON-NLS-1$//$NON-NLS-2$ + } + public void testClass_55_79231() throws Exception { + StringWriter writer = new StringWriter(); + writer.write( "class Boo{};//vp1 \n" ); //$NON-NLS-1$ + writer.write( "class Foo{ \n" ); //$NON-NLS-1$ + writer.write( " Foo() { \n" ); //$NON-NLS-1$ + writer.write( " class Boo{}; \n" ); //$NON-NLS-1$ + writer.write( " Boo t; \n" ); //$NON-NLS-1$ + writer.write( " } \n" ); //$NON-NLS-1$ + writer.write( "}; \n" ); //$NON-NLS-1$ + + String contents = writer.toString(); + IFile file = importFile( "t.cpp", contents ); //$NON-NLS-1$ + //defect is that the inner class defined in a method is also renamed, when it + // shouldn't be. + int offset = contents.indexOf( "Boo{};//vp1" ) ; //$NON-NLS-1$ + Change changes = getRefactorChanges(file, offset, "Ooga" ); //$NON-NLS-1$ + + assertTotalChanges( 1, changes ); + assertChange( changes, file, contents.indexOf("Boo{};//vp1"), 3, "Ooga" ); //$NON-NLS-1$//$NON-NLS-2$ + } + + public void testClass_55_72748() throws Exception { + StringWriter writer = new StringWriter(); + writer.write( "class Foo{};//vp1 \n" ); //$NON-NLS-1$ + writer.write( "void f(){ \n" ); //$NON-NLS-1$ + writer.write( " Foo *somePtr; \n" ); //$NON-NLS-1$ + writer.write( " if (somePtr == reinterpret_cast(0)){} \n" ); //$NON-NLS-1$ + writer.write( "} \n" ); //$NON-NLS-1$ + + String contents = writer.toString(); + IFile file = importFile( "t.cpp", contents ); //$NON-NLS-1$ + //defect is that the Foo in <> is not renamed + int offset = contents.indexOf( "Foo{};//vp1" ) ; //$NON-NLS-1$ + Change changes = getRefactorChanges(file, offset, "Ooga" ); //$NON-NLS-1$ + + assertTotalChanges( 3, changes ); + assertChange( changes, file, contents.indexOf("Foo{};//vp1"), 3, "Ooga" ); //$NON-NLS-1$//$NON-NLS-2$ + assertChange( changes, file, contents.indexOf("Foo *somePtr"), 3, "Ooga" ); //$NON-NLS-1$//$NON-NLS-2$ + assertChange( changes, file, contents.indexOf("Foo*>(0)"), 3, "Ooga" ); //$NON-NLS-1$//$NON-NLS-2$ + } + public void testClass_56() throws Exception { + StringWriter writer = new StringWriter(); + writer.write( "class Foo{};//vp1,rn1 \n" ); //$NON-NLS-1$ + writer.write( "class Derived: public Foo{//rn2 \n" ); //$NON-NLS-1$ + writer.write( " Derived():Foo(){}//rn3 \n" ); //$NON-NLS-1$ + writer.write( "}; \n" ); //$NON-NLS-1$ + + String contents = writer.toString(); + IFile file = importFile( "t.cpp", contents ); //$NON-NLS-1$ + //defect is that the inner class defined in a method is also renamed, when it + // shouldn't be. + int offset = contents.indexOf( "Foo{};//vp1" ) ; //$NON-NLS-1$ + Change changes = getRefactorChanges(file, offset, "Ooga" ); //$NON-NLS-1$ + + assertTotalChanges( 3, changes ); + assertChange( changes, file, contents.indexOf("Foo{};//vp1"), 3, "Ooga" ); //$NON-NLS-1$//$NON-NLS-2$ + assertChange( changes, file, contents.indexOf("Foo{//rn2"), 3, "Ooga" ); //$NON-NLS-1$//$NON-NLS-2$ + assertChange( changes, file, contents.indexOf("Foo(){}//rn3"), 3, "Ooga" ); //$NON-NLS-1$//$NON-NLS-2$ + } + public void testAttribute_61() throws Exception { + StringWriter writer = new StringWriter(); + writer.write( "class Foo{ \n" ); //$NON-NLS-1$ + writer.write( " private: static int count;//vp1 \n" ); //$NON-NLS-1$ + writer.write( "}; \n" ); //$NON-NLS-1$ + String header = writer.toString(); + IFile h = importFile( "Foo.hh", header ); //$NON-NLS-1$ + writer = new StringWriter(); + writer.write( "#include \"Foo.hh\" \n" ); //$NON-NLS-1$ + writer.write( "int Foo::count=10; \n" ); //$NON-NLS-1$ + + String source = writer.toString(); + IFile cpp = importFile( "Foo.cpp", source ); //$NON-NLS-1$ + int offset = header.indexOf( "count" ) ; //$NON-NLS-1$ + Change changes = getRefactorChanges(h, offset, "ooga" ); //$NON-NLS-1$ + + assertTotalChanges( 2, changes ); + assertChange( changes, h, header.indexOf("count"), 5, "ooga" ); //$NON-NLS-1$//$NON-NLS-2$ + assertChange( changes, cpp, source.indexOf("count"), 5, "ooga" ); //$NON-NLS-1$//$NON-NLS-2$ + + } + public void testEnumerator_62() throws Exception { + StringWriter writer = new StringWriter(); + writer.write( "enum Foo{E0, E1};//vp1 \n" ); //$NON-NLS-1$ + String header = writer.toString(); + IFile h = importFile( "Foo.hh", header ); //$NON-NLS-1$ + writer = new StringWriter(); + writer.write( "#include \"Foo.hh\" \n" ); //$NON-NLS-1$ + writer.write( "void f() { \n" ); //$NON-NLS-1$ + writer.write( " int i=E1; \n" ); //$NON-NLS-1$ + writer.write( "} \n" ); //$NON-NLS-1$ + + String source = writer.toString(); + IFile cpp=importFile( "Foo.cpp", source ); //$NON-NLS-1$ + int offset = header.indexOf( "E1" ) ; //$NON-NLS-1$ + getRefactorChanges(h, offset, "Ooga" ); //$NON-NLS-1$ + Change changes = getRefactorChanges(h, offset, "ooga" ); //$NON-NLS-1$ + + assertTotalChanges( 2, changes ); + assertChange( changes, h, header.indexOf("E1"), 2, "ooga" ); //$NON-NLS-1$//$NON-NLS-2$ + assertChange( changes, cpp, source.indexOf("E1"), 2, "ooga" ); //$NON-NLS-1$//$NON-NLS-2$ + + } + public void testAttribute_63() throws Exception { + StringWriter writer = new StringWriter(); + writer.write( "class Foo{ \n" ); //$NON-NLS-1$ + writer.write( " int att; \n" ); //$NON-NLS-1$ + writer.write( " Foo(int i); \n" ); //$NON-NLS-1$ + writer.write( "}; \n" ); //$NON-NLS-1$ + String header = writer.toString(); + IFile h = importFile( "Foo.hh", header ); //$NON-NLS-1$ + writer = new StringWriter(); + writer.write( "#include \"Foo.hh\" \n" ); //$NON-NLS-1$ + writer.write( "Foo::Foo(int i): att(i) {} \n" ); //$NON-NLS-1$ + + String source = writer.toString(); + IFile cpp = importFile( "Foo.cpp", source ); //$NON-NLS-1$ + int offset = header.indexOf( "att" ) ; //$NON-NLS-1$ + Change changes = getRefactorChanges(h, offset, "ooga" ); //$NON-NLS-1$ + + assertTotalChanges( 2, changes ); + assertChange( changes, h, header.indexOf("att"), 3, "ooga" ); //$NON-NLS-1$//$NON-NLS-2$ + assertChange( changes, cpp, source.indexOf("att"), 3, "ooga" ); //$NON-NLS-1$//$NON-NLS-2$ + + } + public void testAttribute_64() throws Exception { + StringWriter writer = new StringWriter(); + writer.write( "class Foo{ \n" ); //$NON-NLS-1$ + writer.write( " private: \n" ); //$NON-NLS-1$ + writer.write( " int b;//vp1,rn1 \n" ); //$NON-NLS-1$ + writer.write( " int m(int b) { \n" ); //$NON-NLS-1$ + writer.write( " return b; \n" ); //$NON-NLS-1$ + writer.write( " } \n" ); //$NON-NLS-1$ + writer.write( " int n() { \n" ); //$NON-NLS-1$ + writer.write( " return b;//rn2 \n" ); //$NON-NLS-1$ + writer.write( " } \n" ); //$NON-NLS-1$ + writer.write( " int o() { \n" ); //$NON-NLS-1$ + writer.write( " int b=2; \n" ); //$NON-NLS-1$ + writer.write( " return b; \n" ); //$NON-NLS-1$ + writer.write( " } \n" ); //$NON-NLS-1$ + writer.write( "}; \n" ); //$NON-NLS-1$ + String header = writer.toString(); + IFile h = importFile( "Foo.hh", header ); //$NON-NLS-1$ + int offset = header.indexOf( "b;//vp1" ) ; //$NON-NLS-1$ + Change changes = getRefactorChanges(h, offset, "ooga" ); //$NON-NLS-1$ + + assertTotalChanges( 2, changes ); + assertChange( changes, h, header.indexOf("b;//vp1"), 1, "ooga" ); //$NON-NLS-1$//$NON-NLS-2$ + assertChange( changes, h, header.indexOf("b;//rn2"), 1, "ooga" ); //$NON-NLS-1$//$NON-NLS-2$ + + } + public void testAttribute_65() throws Exception { + StringWriter writer = new StringWriter(); + writer.write( "class A{ \n" ); //$NON-NLS-1$ + writer.write( " int x(); \n" ); //$NON-NLS-1$ + writer.write( "}; \n" ); //$NON-NLS-1$ + writer.write( "class B{ \n" ); //$NON-NLS-1$ + writer.write( " friend class A; \n" ); //$NON-NLS-1$ + writer.write( " private: \n" ); //$NON-NLS-1$ + writer.write( " int att; \n" ); //$NON-NLS-1$ + writer.write( "}; \n" ); //$NON-NLS-1$ + String header = writer.toString(); + IFile h = importFile( "Foo.hh", header ); //$NON-NLS-1$ + writer = new StringWriter(); + writer.write( "#include \"Foo.hh\" \n" ); //$NON-NLS-1$ + writer.write( "int A::x() { \n" ); //$NON-NLS-1$ + writer.write( " B b; \n" ); //$NON-NLS-1$ + writer.write( " int att=b.att; \n" ); //$NON-NLS-1$ + writer.write( "} \n" ); //$NON-NLS-1$ + String source = writer.toString(); + IFile cpp = importFile( "Foo.cpp", source ); //$NON-NLS-1$ + int offset = header.indexOf( "att" ) ; //$NON-NLS-1$ + Change changes = getRefactorChanges(h, offset, "ooga" ); //$NON-NLS-1$ + + assertTotalChanges( 2, changes ); + assertChange( changes, h, header.indexOf("att"), 3, "ooga" ); //$NON-NLS-1$//$NON-NLS-2$ + assertChange( changes, cpp, source.indexOf("att;"), 3, "ooga" ); //$NON-NLS-1$//$NON-NLS-2$ + + } + public void testNamespace_66() throws Exception { + StringWriter writer = new StringWriter(); + writer.write( "namespace Foo/*vp1*/{ \n" ); //$NON-NLS-1$ + writer.write( " namespace Baz/*vp2*/ { \n" ); //$NON-NLS-1$ + writer.write( " int i; \n" ); //$NON-NLS-1$ + writer.write( " } \n" ); //$NON-NLS-1$ + writer.write( " using namespace Baz; \n" ); //$NON-NLS-1$ + writer.write( "} \n" ); //$NON-NLS-1$ + writer.write( "void f() { \n" ); //$NON-NLS-1$ + writer.write( " Foo::i = 1; \n" ); //$NON-NLS-1$ + writer.write( "} \n" ); //$NON-NLS-1$ + + String contents = writer.toString(); + IFile file = importFile( "t.cpp", contents ); //$NON-NLS-1$ + //vp1 Foo with ref in function + int offset = contents.indexOf( "Foo/*vp1*/" ) ; //$NON-NLS-1$ + Change changes = getRefactorChanges(file, offset, "Ooga" ); //$NON-NLS-1$ + assertTotalChanges( 2, changes ); + assertChange( changes, file, contents.indexOf("Foo/*vp1*/"), 3, "Ooga" ); //$NON-NLS-1$//$NON-NLS-2$ + assertChange( changes, file, contents.indexOf("Foo::"), 3, "Ooga" ); //$NON-NLS-1$//$NON-NLS-2$ + //vp2 nested Baz with ref in using + offset = contents.indexOf( "Baz/*vp2*/" ) ; //$NON-NLS-1$ + changes = getRefactorChanges(file, offset, "Wooga" ); //$NON-NLS-1$ + assertTotalChanges( 2, changes ); + assertChange( changes, file, contents.indexOf("Baz/*vp2*/"), 3, "Wooga" ); //$NON-NLS-1$//$NON-NLS-2$ + assertChange( changes, file, contents.indexOf("Baz;"), 3, "Wooga" ); //$NON-NLS-1$//$NON-NLS-2$ + + } + + public void testNamespace_66_79281() throws Exception { + StringWriter writer = new StringWriter(); + writer.write( "namespace Foo{ \n" ); //$NON-NLS-1$ + writer.write( " int i; \n" ); //$NON-NLS-1$ + writer.write( "} \n" ); //$NON-NLS-1$ + writer.write( "namespace Bar/*vp1*/ = Foo; \n" ); //$NON-NLS-1$ + writer.write( "void f() { \n" ); //$NON-NLS-1$ + writer.write( " Bar::i = 1; \n" ); //$NON-NLS-1$ + writer.write( "} \n" ); //$NON-NLS-1$ + + String contents = writer.toString(); + IFile file = importFile( "t.cpp", contents ); //$NON-NLS-1$ + int offset = contents.indexOf( "Bar/*vp1*/" ) ; //$NON-NLS-1$ + Change changes = getRefactorChanges(file, offset, "Ooga" ); //$NON-NLS-1$ + assertTotalChanges( 2, changes ); + assertChange( changes, file, contents.indexOf("Bar/*vp1*/"), 3, "Ooga" ); //$NON-NLS-1$//$NON-NLS-2$ + assertChange( changes, file, contents.indexOf("Bar::"), 3, "Ooga" ); //$NON-NLS-1$//$NON-NLS-2$ + } + + public void testNamespace_66_79282() throws Exception { + StringWriter writer = new StringWriter(); + writer.write( "namespace Foo/*vp1*/{} \n" ); //$NON-NLS-1$ + writer.write( "namespace Bar = Foo; \n" ); //$NON-NLS-1$ + + String contents = writer.toString(); + IFile file = importFile( "t.cpp", contents ); //$NON-NLS-1$ + //defect is Foo on line 2 is not renamed + int offset = contents.indexOf( "Foo/*vp1*/" ) ; //$NON-NLS-1$ + Change changes = getRefactorChanges(file, offset, "Ooga" ); //$NON-NLS-1$ + assertTotalChanges( 2, changes ); + assertChange( changes, file, contents.indexOf("Foo/*vp1*/"), 3, "Ooga" ); //$NON-NLS-1$//$NON-NLS-2$ + assertChange( changes, file, contents.indexOf("Foo;"), 3, "Ooga" ); //$NON-NLS-1$//$NON-NLS-2$ + } + public void testFunction_67() throws Exception { + StringWriter writer = new StringWriter(); + writer.write( "void foo/*vp1*/(){}//rn1 \n" ); //$NON-NLS-1$ + writer.write( "void bar(){ \n" ); //$NON-NLS-1$ + writer.write( " foo();//rn2 \n" ); //$NON-NLS-1$ + writer.write( "} \n" ); //$NON-NLS-1$ + writer.write( "namespace N{ \n" ); //$NON-NLS-1$ + writer.write( " class A{ \n" ); //$NON-NLS-1$ + writer.write( " A() {foo();}//rn3 \n" ); //$NON-NLS-1$ + writer.write( " }; \n" ); //$NON-NLS-1$ + writer.write( "} \n" ); //$NON-NLS-1$ + + String contents = writer.toString(); + IFile file = importFile( "t.cpp", contents ); //$NON-NLS-1$ + int offset = contents.indexOf( "foo/*vp1*/" ) ; //$NON-NLS-1$ + Change changes = getRefactorChanges(file, offset, "ooga" ); //$NON-NLS-1$ + assertTotalChanges( 3, changes ); + assertChange( changes, file, contents.indexOf("foo/*vp1*/"), 3, "ooga" ); //$NON-NLS-1$//$NON-NLS-2$ + assertChange( changes, file, contents.indexOf("foo();//rn2"), 3, "ooga" ); //$NON-NLS-1$//$NON-NLS-2$ + assertChange( changes, file, contents.indexOf("foo();}//rn3"), 3, "ooga" ); //$NON-NLS-1$//$NON-NLS-2$ + } + public void testVariable_68() throws Exception { + StringWriter writer = new StringWriter(); + writer.write( "class A{ \n" ); //$NON-NLS-1$ + writer.write( " public: int i; \n" ); //$NON-NLS-1$ + writer.write( "}; \n" ); //$NON-NLS-1$ + writer.write( "A var;//vp1,rn1 \n" ); //$NON-NLS-1$ + writer.write( "void f(){ \n" ); //$NON-NLS-1$ + writer.write( " int j = ::var.i;//rn2 \n" ); //$NON-NLS-1$ + writer.write( "} \n" ); //$NON-NLS-1$ + writer.write( "class B{ \n" ); //$NON-NLS-1$ + writer.write( " void g(){ \n" ); //$NON-NLS-1$ + writer.write( " var.i=3;//rn3 \n" ); //$NON-NLS-1$ + writer.write( " } \n" ); //$NON-NLS-1$ + writer.write( "}; \n" ); //$NON-NLS-1$ + + String contents = writer.toString(); + IFile file = importFile( "t.cpp", contents ); //$NON-NLS-1$ + int offset = contents.indexOf( "var;//vp1" ) ; //$NON-NLS-1$ + Change changes = getRefactorChanges(file, offset, "ooga" ); //$NON-NLS-1$ + assertTotalChanges( 3, changes ); + assertChange( changes, file, contents.indexOf("var;//vp1"), 3, "ooga" ); //$NON-NLS-1$//$NON-NLS-2$ + assertChange( changes, file, contents.indexOf("var.i;//rn2"), 3, "ooga" ); //$NON-NLS-1$//$NON-NLS-2$ + assertChange( changes, file, contents.indexOf("var.i=3;//rn3"), 3, "ooga" ); //$NON-NLS-1$//$NON-NLS-2$ + } + public void testVariable_68_79295() throws Exception { + StringWriter writer = new StringWriter(); + writer.write( "int var;//vp1 \n" ); //$NON-NLS-1$ + writer.write( "void f(int var){ \n" ); //$NON-NLS-1$ + writer.write( " int i = var; \n" ); //$NON-NLS-1$ + writer.write( "} \n" ); //$NON-NLS-1$ + + String contents = writer.toString(); + IFile file = importFile( "t.cpp", contents ); //$NON-NLS-1$ + //defect is the argument and local variable var are incorrectly renamed + int offset = contents.indexOf( "var;//vp1" ) ; //$NON-NLS-1$ + Change changes = getRefactorChanges(file, offset, "ooga" ); //$NON-NLS-1$ + assertTotalChanges( 1, changes ); + assertChange( changes, file, contents.indexOf("var;//vp1"), 3, "ooga" ); //$NON-NLS-1$//$NON-NLS-2$ + } + //similar to test 92, except this one will continue with warning, or error status + //while case in 92 must stop refactor with fatal status + public void testClass_81_72620() throws Exception { + StringWriter writer = new StringWriter(); + writer.write( "union u_haul{}; \n" ); //$NON-NLS-1$ + writer.write( "struct s_haul{}; \n" ); //$NON-NLS-1$ + String contents = writer.toString(); + IFile file = importFile( "t.cpp", contents ); //$NON-NLS-1$ + int offset = contents.indexOf( "s_haul" ) ; //$NON-NLS-1$ + try { + getRefactorChanges(file, offset, "u_haul" ); //$NON-NLS-1$ + } catch (AssertionFailedError e) { + assertTrue(e.getMessage().startsWith("Input check on u_haul failed.")); //$NON-NLS-1$ + return; + } + fail ("An error should have occurred in the input check."); //$NON-NLS-1$ + } + public void testVariable_88_72617() throws Exception { + StringWriter writer = new StringWriter(); + writer.write( "class A{}; \n" ); //$NON-NLS-1$ + writer.write( "A a;//vp1 \n" ); //$NON-NLS-1$ + String header = writer.toString(); + IFile h = importFile( "Foo.hh", header ); //$NON-NLS-1$ + writer = new StringWriter(); + writer.write( "#include \"Foo.hh\" \n" ); //$NON-NLS-1$ + writer.write( "void f() { \n" ); //$NON-NLS-1$ + writer.write( " A a; \n" ); //$NON-NLS-1$ + writer.write( "} \n" ); //$NON-NLS-1$ + String source = writer.toString(); + importFile( "Foo.cpp", source ); //$NON-NLS-1$ + int offset = header.indexOf( "a;//vp1" ) ; //$NON-NLS-1$ + Change changes = getRefactorChanges(h, offset, "ooga" ); //$NON-NLS-1$ + + assertTotalChanges( 1, changes ); + assertChange( changes, h, header.indexOf("a;//vp1"), 1, "ooga" ); //$NON-NLS-1$//$NON-NLS-2$ + } + //2 ways to test name collistion on same type: + //if you don't know the error message, catch on getRefactorChanges + //or if you want to verify a message or severity, use getRefactorMessages + //and getRefactorSeverity + public void testClass_92A() throws Exception { + StringWriter writer = new StringWriter(); + writer.write( "class Boo{}; \n" ); //$NON-NLS-1$ + writer.write( " void f() {} \n" ); //$NON-NLS-1$ + writer.write( "}; \n" ); //$NON-NLS-1$ + writer.write( "class Foo/*vp1*/{}; \n" ); //$NON-NLS-1$ + + String contents = writer.toString(); + IFile file = importFile( "t.cpp", contents ); //$NON-NLS-1$ + int offset = contents.indexOf( "Foo/*vp1*/" ) ; //$NON-NLS-1$ + try { + getRefactorChanges(file, offset, "Boo" ); //$NON-NLS-1$ + } catch (AssertionFailedError e) { + assertTrue(e.getMessage().startsWith("Input check on Boo failed.")); //$NON-NLS-1$ + return; + } + fail ("An error or warning should have occurred in the input check."); //$NON-NLS-1$ + } + public void testClass_92B() throws Exception { + StringWriter writer = new StringWriter(); + writer.write( "class A{}; \n" ); //$NON-NLS-1$ + writer.write( "class B{};//vp1 \n" ); //$NON-NLS-1$ + + String contents = writer.toString(); + IFile file = importFile( "t.cpp", contents ); //$NON-NLS-1$ + int offset = contents.indexOf( "B{};//vp1" ) ; //$NON-NLS-1$ + + String[] messages = getRefactorMessages( file, offset, "A" ); //$NON-NLS-1$ + assertEquals(1, messages.length); + assertEquals("A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: A \n" + + "Conflicting element type: Type", messages[0]); //$NON-NLS-1$ + // assert that you cannot refactor because severity is FATAL (4) + int s = getRefactorSeverity(file, offset, "A"); //$NON-NLS-1$ + assertEquals(RefactoringStatus.ERROR,s); + } + + public void testRenameParticipant() throws Exception { + TestRenameParticipant.reset(); + StringWriter writer = new StringWriter(); + writer.write( "class A{}; " ); //$NON-NLS-1$ + String contents = writer.toString(); + IFile file = importFile( "t.cpp", contents ); //$NON-NLS-1$ + int offset = contents.indexOf( "A" ) ; //$NON-NLS-1$ + getRefactorChanges(file, offset, "B"); //$NON-NLS-1$ + assertEquals(1, TestRenameParticipant.getConditionCheckCount()); + assertEquals(1, TestRenameParticipant.getCreateChangeCount()); + Object element= TestRenameParticipant.getElement(); + + assertNotNull(element); + assertTrue(element instanceof IBinding); + IBinding binding= (IBinding) element; + assertEquals(binding.getName(), "A"); //$NON-NLS-1$ + + RenameArguments args= TestRenameParticipant.staticGetArguments(); + assertNotNull(args); + assertEquals("B", args.getNewName()); //$NON-NLS-1$ + } +} diff --git a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/refactoring/rename/RenameTemplatesTests.java b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/refactoring/rename/RenameTemplatesTests.java new file mode 100644 index 00000000000..b8852a6c92e --- /dev/null +++ b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/refactoring/rename/RenameTemplatesTests.java @@ -0,0 +1,67 @@ +/******************************************************************************* + * Copyright (c) 2005, 2006 Wind River Systems, Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Markus Schorn - initial API and implementation + *******************************************************************************/ + +package org.eclipse.cdt.ui.tests.refactoring.rename; + +import java.io.StringWriter; + +import junit.framework.Test; +import junit.framework.TestSuite; + +import org.eclipse.core.resources.IFile; +import org.eclipse.ltk.core.refactoring.Change; +import org.eclipse.ltk.core.refactoring.RefactoringStatus; + +/** + * @author markus.schorn@windriver.com + */ +public class RenameTemplatesTests extends RenameTests { + + public RenameTemplatesTests(String name) { + super(name); + } + public static Test suite(){ + return suite(true); + } + public static Test suite( boolean cleanup ) { + TestSuite suite = new TestSuite(RenameTemplatesTests.class); + if (cleanup) { + suite.addTest( new RefactoringTests("cleanupProject") ); //$NON-NLS-1$ + } + return suite; + } + + + public void testClassTemplate() throws Exception { + StringWriter writer = new StringWriter(); + writer.write("template \n"); //$NON-NLS-1$ + writer.write("class Array { \n"); //$NON-NLS-1$ + writer.write("public: \n"); //$NON-NLS-1$ + writer.write(" Array(unsigned sz) {} \n"); //$NON-NLS-1$ + writer.write(" ~Array(){} \n"); //$NON-NLS-1$ + writer.write(" Type& operator[] (unsigned idx); \n"); //$NON-NLS-1$ + writer.write("}; \n"); //$NON-NLS-1$ + writer.write("template \n"); //$NON-NLS-1$ + writer.write("inline Type& Array::operator[] (unsigned index) {\n"); //$NON-NLS-1$ + writer.write(" return 1; \n"); //$NON-NLS-1$ + writer.write("}; \n"); //$NON-NLS-1$ + String contents = writer.toString(); + IFile cpp= importFile("test.cpp", contents ); //$NON-NLS-1$ + + int offset1= contents.indexOf("Array"); //$NON-NLS-1$ + + RefactoringStatus stat= checkConditions(cpp, offset1, "WELT"); //$NON-NLS-1$ + assertRefactoringOk(stat); + + Change ch= getRefactorChanges(cpp, offset1, "WELT"); //$NON-NLS-1$ + assertTotalChanges(4, ch); + } +} diff --git a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/refactoring/rename/RenameTests.java b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/refactoring/rename/RenameTests.java new file mode 100644 index 00000000000..d4d4adfe91a --- /dev/null +++ b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/refactoring/rename/RenameTests.java @@ -0,0 +1,119 @@ +/******************************************************************************* + * Copyright (c) 2005 Wind River Systems, Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Markus Schorn - initial API and implementation + ******************************************************************************/ + +package org.eclipse.cdt.ui.tests.refactoring.rename; + +import org.eclipse.core.resources.IFile; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.NullProgressMonitor; +import org.eclipse.ltk.core.refactoring.Change; +import org.eclipse.ltk.core.refactoring.RefactoringStatus; +import org.eclipse.ltk.core.refactoring.RefactoringStatusEntry; + +import org.eclipse.cdt.internal.ui.refactoring.rename.CRefactoringArgument; +import org.eclipse.cdt.internal.ui.refactoring.rename.CRefactory; +import org.eclipse.cdt.internal.ui.refactoring.rename.CRenameProcessor; +import org.eclipse.cdt.internal.ui.refactoring.rename.CRenameRefactoring; +import org.eclipse.cdt.internal.ui.refactoring.rename.TextSearchWrapper; + +/** + * @author markus.schorn@windriver.com + */ +public class RenameTests extends RefactoringTests { + + public RenameTests(String name) { + super(name); + } + + public RenameTests() { + } + + /** + * @param element The CElement to rename + * @param newName The new name for the element + * @return + * @throws Exception + */ + public Change getRefactorChanges(IFile file, int offset, String newName) throws Exception { + CRenameRefactoring proc = createRefactoring(file, offset, newName); + + RefactoringStatus rs = checkConditions(proc); + if (!rs.hasError()) { + Change change = proc.createChange( new NullProgressMonitor() ); + return change; + } + + fail ("Input check on "+ newName + " failed. "+rs.getEntryMatchingSeverity(RefactoringStatus.ERROR) ); //$NON-NLS-1$ //$NON-NLS-2$ + //rs.getFirstMessage(RefactoringStatus.ERROR) is not the message displayed in + //the UI for renaming a method to a constructor, the first message which is only + //a warning is shown in the UI. If you click preview, then the error and the warning + //is shown. + return null; + } + + private CRenameRefactoring createRefactoring(IFile file, int offset, String newName) { + CRefactoringArgument arg= new CRefactoringArgument(file, offset, 0); + CRenameProcessor proc= new CRenameProcessor(CRefactory.getInstance(), arg); + proc.setReplacementText( newName ); + proc.setSelectedOptions(-1); + proc.setScope(TextSearchWrapper.SCOPE_WORKSPACE); + return new CRenameRefactoring(proc); + } + + public String[] getRefactorMessages(IFile file, int offset, String newName) throws Exception { + String[] result; + CRenameRefactoring proc = createRefactoring(file, offset, newName); + RefactoringStatus rs = checkConditions(proc); + if (!rs.hasWarning()){ + fail ("Input check on "+ newName + " passed. There should have been warnings or errors. ") ; //$NON-NLS-1$ //$NON-NLS-2$ + return null; + } + RefactoringStatusEntry[] rse = rs.getEntries(); + result = new String[rse.length]; + for (int i=0; i< rse.length; i++){ + RefactoringStatusEntry entry = rse[i]; + result[i]=entry.getMessage(); + + } + return result; + } + + public RefactoringStatus checkConditions(IFile file, int offset, String newName) throws Exception { + CRenameRefactoring proc = createRefactoring(file, offset, newName); + return checkConditions(proc); + } + + private RefactoringStatus checkConditions(CRenameRefactoring proc) throws CoreException { + RefactoringStatus rs =proc.checkInitialConditions(new NullProgressMonitor() ); + if (!rs.hasError()){ + rs= proc.checkFinalConditions(new NullProgressMonitor()); + } + return rs; + } + + public int getRefactorSeverity(IFile file, int offset, String newName) throws Exception { + CRenameRefactoring proc = createRefactoring(file, offset, newName); + RefactoringStatus rs = checkConditions(proc); + + return (rs.getSeverity()); + } + + protected int countOccurrences(String contents, String lookup) { + int idx= contents.indexOf(lookup); + int count= 0; + while (idx >=0) { + count++; + idx= contents.indexOf(lookup, idx+lookup.length()); + } + return count; + } + +} diff --git a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/refactoring/rename/RenameTypeTests.java b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/refactoring/rename/RenameTypeTests.java new file mode 100644 index 00000000000..01c23f6a7cf --- /dev/null +++ b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/refactoring/rename/RenameTypeTests.java @@ -0,0 +1,2298 @@ +/******************************************************************************* + * Copyright (c) 2005, 2007 Wind River Systems, Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Markus Schorn - initial API and implementation + *******************************************************************************/ + +package org.eclipse.cdt.ui.tests.refactoring.rename; + +import java.io.StringWriter; + +import junit.framework.Test; +import junit.framework.TestSuite; + +import org.eclipse.core.resources.IFile; +import org.eclipse.ltk.core.refactoring.Change; +import org.eclipse.ltk.core.refactoring.RefactoringStatus; + +/** + * @author markus.schorn@windriver.com + */ +public class RenameTypeTests extends RenameTests { + + public RenameTypeTests(String name) { + super(name); + } + public static Test suite(){ + return suite(true); + } + public static Test suite( boolean cleanup ) { + TestSuite suite = new TestSuite(RenameTypeTests.class); + if (cleanup) { + suite.addTest( new RefactoringTests("cleanupProject") ); //$NON-NLS-1$ + } + return suite; + } + + + public void testClassNameConflicts() throws Exception { + createCppFwdDecls("cpp_fwd.hh"); //$NON-NLS-1$ + createCppDefs("cpp_def.hh"); //$NON-NLS-1$ + StringWriter writer = new StringWriter(); + writer.write("#include \"cpp_fwd.hh\" \n"); //$NON-NLS-1$ + writer.write("#include \"cpp_def.hh\" \n"); //$NON-NLS-1$ + writer.write("class v1 { \n"); //$NON-NLS-1$ + writer.write(" int v; \n"); //$NON-NLS-1$ + writer.write("}; \n"); //$NON-NLS-1$ + writer.write("class v2 { \n"); //$NON-NLS-1$ + writer.write(" int v; \n"); //$NON-NLS-1$ + writer.write("}; \n"); //$NON-NLS-1$ + writer.write("class v3 { \n"); //$NON-NLS-1$ + writer.write(" int v; \n"); //$NON-NLS-1$ + writer.write("}; \n"); //$NON-NLS-1$ + writer.write("class v4 { \n"); //$NON-NLS-1$ + writer.write(" int function(); \n"); //$NON-NLS-1$ + writer.write("}; \n"); //$NON-NLS-1$ + writer.write("int v4::function(){} \n"); //$NON-NLS-1$ + writer.write("void f(int par1){ \n"); //$NON-NLS-1$ + writer.write(" { \n"); //$NON-NLS-1$ + writer.write(" int w1; v1::v++; \n"); //$NON-NLS-1$ + writer.write(" } \n"); //$NON-NLS-1$ + writer.write("} \n"); //$NON-NLS-1$ + writer.write("void class_def::method(int par2) { \n"); //$NON-NLS-1$ + writer.write(" { \n"); //$NON-NLS-1$ + writer.write(" int w2; v2::v++; \n"); //$NON-NLS-1$ + writer.write(" } \n"); //$NON-NLS-1$ + writer.write("} \n"); //$NON-NLS-1$ + writer.write("static void class_def::static_method(int par3) { \n"); //$NON-NLS-1$ + writer.write(" { \n"); //$NON-NLS-1$ + writer.write(" int w3; v3::v++; \n"); //$NON-NLS-1$ + writer.write(" } \n"); //$NON-NLS-1$ + writer.write("} \n"); //$NON-NLS-1$ + String contents = writer.toString(); + IFile cpp= importFile("test.cpp", contents ); //$NON-NLS-1$ + + int offset1= contents.indexOf("v1"); //$NON-NLS-1$ + int offset2= contents.indexOf("v2"); //$NON-NLS-1$ + int offset3= contents.indexOf("v3"); //$NON-NLS-1$ + int offset4= contents.indexOf("v4"); //$NON-NLS-1$ + + // conflicting renamings + RefactoringStatus status= checkConditions(cpp, offset1, "w1"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, contents.indexOf("par1"), "v1"); //$NON-NLS-1$ //$NON-NLS-2$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Shadowing \n" + + "New element: v1 \n" + + "Conflicting element type: Constructor"); //$NON-NLS-1$ + status= checkConditions(cpp, offset1, "par1"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "extern_var"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "var_def"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "enum_item"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset2, "w2"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset2, "par2"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset2, "extern_var"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset2, "var_def"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset2, "enum_item"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset3, "w3"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset3, "par3"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset3, "extern_var"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset3, "var_def"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset3, "enum_item"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset4, "extern_var"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset4, "var_def"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset4, "enum_item"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "member"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "method"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "static_member"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "static_method"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset2, "member"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset2, "method"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset2, "static_member"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset2, "static_method"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset3, "static_member"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset3, "static_method"); //$NON-NLS-1$ + assertRefactoringOk(status); + + // renamings conflicting with global stuff. + status= checkConditions(cpp, offset1, "func_proto"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "func_proto_ov"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "func_def"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "func_def_ov"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset2, "func_proto"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset2, "func_proto_ov"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset2, "func_def"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset2, "func_def_ov"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset3, "func_proto"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset3, "func_proto_ov"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset3, "func_def"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset3, "func_def_ov"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset4, "func_proto"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset4, "func_proto_ov"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset4, "func_def"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset4, "func_def_ov"); //$NON-NLS-1$ + assertRefactoringOk(status); + + // renamings colliding with types. + // renamings colliding with types. + status= checkConditions(cpp, offset1, "class_fwd"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: class_fwd \n" + + "Conflicting element type: Type"); //$NON-NLS-1$ + status= checkConditions(cpp, offset1, "struct_fwd"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: struct_fwd \n" + + "Conflicting element type: Type"); //$NON-NLS-1$ + status= checkConditions(cpp, offset1, "union_fwd"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: union_fwd \n" + + "Conflicting element type: Type"); //$NON-NLS-1$ + status= checkConditions(cpp, offset1, "class_def"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: class_def \n" + + "Conflicting element type: Type"); //$NON-NLS-1$ + status= checkConditions(cpp, offset1, "struct_def"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: struct_def \n" + + "Conflicting element type: Type"); //$NON-NLS-1$ + status= checkConditions(cpp, offset1, "union_def"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: union_def \n" + + "Conflicting element type: Type"); //$NON-NLS-1$ + status= checkConditions(cpp, offset1, "enum_def"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: enum_def \n" + + "Conflicting element type: Type"); //$NON-NLS-1$ + status= checkConditions(cpp, offset1, "typedef_def"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: typedef_def \n" + + "Conflicting element type: Type"); //$NON-NLS-1$ + status= checkConditions(cpp, offset1, "namespace_def"); //$NON-NLS-1$ + assertRefactoringWarning(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: namespace_def \n" + + "Conflicting element type: Namespace"); //$NON-NLS-1$ + status= checkConditions(cpp, offset1, "st_member"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "un_member"); //$NON-NLS-1$ + assertRefactoringOk(status); + + status= checkConditions(cpp, offset2, "class_fwd"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: class_fwd \n" + + "Conflicting element type: Type"); //$NON-NLS-1$ + status= checkConditions(cpp, offset2, "struct_fwd"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: struct_fwd \n" + + "Conflicting element type: Type"); //$NON-NLS-1$ + status= checkConditions(cpp, offset2, "union_fwd"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: union_fwd \n" + + "Conflicting element type: Type"); //$NON-NLS-1$ + status= checkConditions(cpp, offset2, "class_def"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: class_def \n" + + "Conflicting element type: Type"); //$NON-NLS-1$ + status= checkConditions(cpp, offset2, "struct_def"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: struct_def \n" + + "Conflicting element type: Type"); //$NON-NLS-1$ + status= checkConditions(cpp, offset2, "union_def"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: union_def \n" + + "Conflicting element type: Type"); //$NON-NLS-1$ + status= checkConditions(cpp, offset2, "enum_def"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: enum_def \n" + + "Conflicting element type: Type"); //$NON-NLS-1$ + status= checkConditions(cpp, offset2, "typedef_def"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: typedef_def \n" + + "Conflicting element type: Type"); //$NON-NLS-1$ + status= checkConditions(cpp, offset2, "namespace_def"); //$NON-NLS-1$ + assertRefactoringWarning(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: namespace_def \n" + + "Conflicting element type: Namespace"); //$NON-NLS-1$ + status= checkConditions(cpp, offset2, "st_member"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset2, "un_member"); //$NON-NLS-1$ + assertRefactoringOk(status); + + status= checkConditions(cpp, offset3, "class_fwd"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: class_fwd \n" + + "Conflicting element type: Type"); //$NON-NLS-1$ + status= checkConditions(cpp, offset3, "struct_fwd"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: struct_fwd \n" + + "Conflicting element type: Type"); //$NON-NLS-1$ + status= checkConditions(cpp, offset3, "union_fwd"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: union_fwd \n" + + "Conflicting element type: Type"); //$NON-NLS-1$ + status= checkConditions(cpp, offset3, "class_def"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: class_def \n" + + "Conflicting element type: Type"); //$NON-NLS-1$ + status= checkConditions(cpp, offset3, "struct_def"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: struct_def \n" + + "Conflicting element type: Type"); //$NON-NLS-1$ + status= checkConditions(cpp, offset3, "union_def"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: union_def \n" + + "Conflicting element type: Type"); //$NON-NLS-1$ + status= checkConditions(cpp, offset3, "enum_def"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: enum_def \n" + + "Conflicting element type: Type"); //$NON-NLS-1$ + status= checkConditions(cpp, offset3, "typedef_def"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: typedef_def \n" + + "Conflicting element type: Type"); //$NON-NLS-1$ + status= checkConditions(cpp, offset3, "namespace_def"); //$NON-NLS-1$ + assertRefactoringWarning(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: namespace_def \n" + + "Conflicting element type: Namespace"); //$NON-NLS-1$ + status= checkConditions(cpp, offset3, "st_member"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset3, "un_member"); //$NON-NLS-1$ + assertRefactoringOk(status); + + status= checkConditions(cpp, offset4, "class_fwd"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: class_fwd \n" + + "Conflicting element type: Type"); //$NON-NLS-1$ + status= checkConditions(cpp, offset4, "struct_fwd"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: struct_fwd \n" + + "Conflicting element type: Type"); //$NON-NLS-1$ + status= checkConditions(cpp, offset4, "union_fwd"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: union_fwd \n" + + "Conflicting element type: Type"); //$NON-NLS-1$ + status= checkConditions(cpp, offset4, "class_def"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: class_def \n" + + "Conflicting element type: Type"); //$NON-NLS-1$ + status= checkConditions(cpp, offset4, "struct_def"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: struct_def \n" + + "Conflicting element type: Type"); //$NON-NLS-1$ + status= checkConditions(cpp, offset4, "union_def"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: union_def \n" + + "Conflicting element type: Type"); //$NON-NLS-1$ + status= checkConditions(cpp, offset4, "enum_def"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: enum_def \n" + + "Conflicting element type: Type"); //$NON-NLS-1$ + status= checkConditions(cpp, offset4, "typedef_def"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: typedef_def \n" + + "Conflicting element type: Type"); //$NON-NLS-1$ + status= checkConditions(cpp, offset4, "namespace_def"); //$NON-NLS-1$ + assertRefactoringWarning(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: namespace_def \n" + + "Conflicting element type: Namespace"); //$NON-NLS-1$ + status= checkConditions(cpp, offset4, "st_member"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset4, "un_member"); //$NON-NLS-1$ + assertRefactoringOk(status); + } + + public void testNamespaceNameConflicts() throws Exception { + createCppFwdDecls("cpp_fwd.hh"); //$NON-NLS-1$ + createCppDefs("cpp_def.hh"); //$NON-NLS-1$ + StringWriter writer = new StringWriter(); + writer.write("#include \"cpp_fwd.hh\" \n"); //$NON-NLS-1$ + writer.write("#include \"cpp_def.hh\" \n"); //$NON-NLS-1$ + writer.write("namespace v4 { \n"); //$NON-NLS-1$ + writer.write(" int function(); \n"); //$NON-NLS-1$ + writer.write("}; \n"); //$NON-NLS-1$ + writer.write("namespace v1 { \n"); //$NON-NLS-1$ + writer.write(" int v; \n"); //$NON-NLS-1$ + writer.write("}; \n"); //$NON-NLS-1$ + writer.write("namespace v2 { \n"); //$NON-NLS-1$ + writer.write(" int v; \n"); //$NON-NLS-1$ + writer.write("}; \n"); //$NON-NLS-1$ + writer.write("namespace v3 { \n"); //$NON-NLS-1$ + writer.write(" int v; \n"); //$NON-NLS-1$ + writer.write("}; \n"); //$NON-NLS-1$ + writer.write("int v4::function(){} \n"); //$NON-NLS-1$ + writer.write("void f(int par1){ \n"); //$NON-NLS-1$ + writer.write(" { \n"); //$NON-NLS-1$ + writer.write(" int w1; v1::v++; \n"); //$NON-NLS-1$ + writer.write(" } \n"); //$NON-NLS-1$ + writer.write("} \n"); //$NON-NLS-1$ + writer.write("void class_def::method(int par2) { \n"); //$NON-NLS-1$ + writer.write(" { \n"); //$NON-NLS-1$ + writer.write(" int w2; v2::v++; \n"); //$NON-NLS-1$ + writer.write(" } \n"); //$NON-NLS-1$ + writer.write("} \n"); //$NON-NLS-1$ + writer.write("static void class_def::static_method(int par3) { \n"); //$NON-NLS-1$ + writer.write(" { \n"); //$NON-NLS-1$ + writer.write(" int w3; v3::v++; \n"); //$NON-NLS-1$ + writer.write(" } \n"); //$NON-NLS-1$ + writer.write("} \n"); //$NON-NLS-1$ + String contents = writer.toString(); + IFile cpp= importFile("test.cpp", contents ); //$NON-NLS-1$ + + int offset1= contents.indexOf("v1"); //$NON-NLS-1$ + int offset2= contents.indexOf("v2"); //$NON-NLS-1$ + int offset3= contents.indexOf("v3"); //$NON-NLS-1$ + int offset4= contents.indexOf("v4"); //$NON-NLS-1$ + + // conflicting renamings + RefactoringStatus status= checkConditions(cpp, offset1, "w1"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, contents.indexOf("par1"), "v1"); //$NON-NLS-1$ //$NON-NLS-2$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "par1"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "extern_var"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "var_def"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "enum_item"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset2, "w2"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset2, "par2"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset2, "extern_var"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset2, "var_def"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset2, "enum_item"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset3, "w3"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset3, "par3"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset3, "extern_var"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset3, "var_def"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset3, "enum_item"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset4, "extern_var"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset4, "var_def"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset4, "enum_item"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "member"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "method"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "static_member"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "static_method"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset2, "member"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset2, "method"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset2, "static_member"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset2, "static_method"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset3, "static_member"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset3, "static_method"); //$NON-NLS-1$ + assertRefactoringOk(status); + + // renamings conflicting with global stuff. + status= checkConditions(cpp, offset1, "func_proto"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "func_proto_ov"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "func_def"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "func_def_ov"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset2, "func_proto"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset2, "func_proto_ov"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset2, "func_def"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset2, "func_def_ov"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset3, "func_proto"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset3, "func_proto_ov"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset3, "func_def"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset3, "func_def_ov"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset4, "func_proto"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset4, "func_proto_ov"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset4, "func_def"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset4, "func_def_ov"); //$NON-NLS-1$ + assertRefactoringOk(status); + + // renamings colliding with types. + status= checkConditions(cpp, offset1, "class_fwd"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: class_fwd \n" + + "Conflicting element type: Type"); //$NON-NLS-1$ + status= checkConditions(cpp, offset1, "struct_fwd"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: struct_fwd \n" + + "Conflicting element type: Type"); //$NON-NLS-1$ + status= checkConditions(cpp, offset1, "union_fwd"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: union_fwd \n" + + "Conflicting element type: Type"); //$NON-NLS-1$ + status= checkConditions(cpp, offset1, "class_def"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: class_def \n" + + "Conflicting element type: Type"); //$NON-NLS-1$ + status= checkConditions(cpp, offset1, "struct_def"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: struct_def \n" + + "Conflicting element type: Type"); //$NON-NLS-1$ + status= checkConditions(cpp, offset1, "union_def"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: union_def \n" + + "Conflicting element type: Type"); //$NON-NLS-1$ + status= checkConditions(cpp, offset1, "enum_def"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: enum_def \n" + + "Conflicting element type: Type"); //$NON-NLS-1$ + status= checkConditions(cpp, offset1, "typedef_def"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: typedef_def \n" + + "Conflicting element type: Type"); //$NON-NLS-1$ + status= checkConditions(cpp, offset1, "namespace_def"); //$NON-NLS-1$ + assertRefactoringWarning(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: namespace_def \n" + + "Conflicting element type: Namespace"); //$NON-NLS-1$ + status= checkConditions(cpp, offset1, "st_member"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "un_member"); //$NON-NLS-1$ + assertRefactoringOk(status); + + status= checkConditions(cpp, offset2, "class_fwd"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: class_fwd \n" + + "Conflicting element type: Type"); //$NON-NLS-1$ + status= checkConditions(cpp, offset2, "struct_fwd"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: struct_fwd \n" + + "Conflicting element type: Type"); //$NON-NLS-1$ + status= checkConditions(cpp, offset2, "union_fwd"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: union_fwd \n" + + "Conflicting element type: Type"); //$NON-NLS-1$ + status= checkConditions(cpp, offset2, "class_def"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: class_def \n" + + "Conflicting element type: Type"); //$NON-NLS-1$ + status= checkConditions(cpp, offset2, "struct_def"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: struct_def \n" + + "Conflicting element type: Type"); //$NON-NLS-1$ + status= checkConditions(cpp, offset2, "union_def"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: union_def \n" + + "Conflicting element type: Type"); //$NON-NLS-1$ + status= checkConditions(cpp, offset2, "enum_def"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: enum_def \n" + + "Conflicting element type: Type"); //$NON-NLS-1$ + status= checkConditions(cpp, offset2, "typedef_def"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: typedef_def \n" + + "Conflicting element type: Type"); //$NON-NLS-1$ + status= checkConditions(cpp, offset2, "namespace_def"); //$NON-NLS-1$ + assertRefactoringWarning(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: namespace_def \n" + + "Conflicting element type: Namespace"); //$NON-NLS-1$ + status= checkConditions(cpp, offset2, "st_member"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset2, "un_member"); //$NON-NLS-1$ + assertRefactoringOk(status); + + status= checkConditions(cpp, offset3, "class_fwd"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: class_fwd \n" + + "Conflicting element type: Type"); //$NON-NLS-1$ + status= checkConditions(cpp, offset3, "struct_fwd"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: struct_fwd \n" + + "Conflicting element type: Type"); //$NON-NLS-1$ + status= checkConditions(cpp, offset3, "union_fwd"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: union_fwd \n" + + "Conflicting element type: Type"); //$NON-NLS-1$ + status= checkConditions(cpp, offset3, "class_def"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: class_def \n" + + "Conflicting element type: Type"); //$NON-NLS-1$ + status= checkConditions(cpp, offset3, "struct_def"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: struct_def \n" + + "Conflicting element type: Type"); //$NON-NLS-1$ + status= checkConditions(cpp, offset3, "union_def"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: union_def \n" + + "Conflicting element type: Type"); //$NON-NLS-1$ + status= checkConditions(cpp, offset3, "enum_def"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: enum_def \n" + + "Conflicting element type: Type"); //$NON-NLS-1$ + status= checkConditions(cpp, offset3, "typedef_def"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: typedef_def \n" + + "Conflicting element type: Type"); //$NON-NLS-1$ + status= checkConditions(cpp, offset3, "namespace_def"); //$NON-NLS-1$ + assertRefactoringWarning(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: namespace_def \n" + + "Conflicting element type: Namespace"); //$NON-NLS-1$ + status= checkConditions(cpp, offset3, "st_member"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset3, "un_member"); //$NON-NLS-1$ + assertRefactoringOk(status); + + status= checkConditions(cpp, offset4, "class_fwd"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: class_fwd \n" + + "Conflicting element type: Type"); //$NON-NLS-1$ + status= checkConditions(cpp, offset4, "struct_fwd"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: struct_fwd \n" + + "Conflicting element type: Type"); //$NON-NLS-1$ + status= checkConditions(cpp, offset4, "union_fwd"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: union_fwd \n" + + "Conflicting element type: Type"); //$NON-NLS-1$ + status= checkConditions(cpp, offset4, "class_def"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: class_def \n" + + "Conflicting element type: Type"); //$NON-NLS-1$ + status= checkConditions(cpp, offset4, "struct_def"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: struct_def \n" + + "Conflicting element type: Type"); //$NON-NLS-1$ + status= checkConditions(cpp, offset4, "union_def"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: union_def \n" + + "Conflicting element type: Type"); //$NON-NLS-1$ + status= checkConditions(cpp, offset4, "enum_def"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: enum_def \n" + + "Conflicting element type: Type"); //$NON-NLS-1$ + status= checkConditions(cpp, offset4, "typedef_def"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: typedef_def \n" + + "Conflicting element type: Type"); //$NON-NLS-1$ + status= checkConditions(cpp, offset4, "namespace_def"); //$NON-NLS-1$ + assertRefactoringWarning(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: namespace_def \n" + + "Conflicting element type: Namespace"); //$NON-NLS-1$ + status= checkConditions(cpp, offset4, "st_member"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset4, "un_member"); //$NON-NLS-1$ + assertRefactoringOk(status); + } + + public void testStructNameConflicts() throws Exception { + createCppFwdDecls("cpp_fwd.hh"); //$NON-NLS-1$ + createCppDefs("cpp_def.hh"); //$NON-NLS-1$ + StringWriter writer = new StringWriter(); + writer.write("#include \"cpp_fwd.hh\" \n"); //$NON-NLS-1$ + writer.write("#include \"cpp_def.hh\" \n"); //$NON-NLS-1$ + writer.write("struct v4 { \n"); //$NON-NLS-1$ + writer.write(" int function(); \n"); //$NON-NLS-1$ + writer.write("}; \n"); //$NON-NLS-1$ + writer.write("struct v1 { \n"); //$NON-NLS-1$ + writer.write(" int v; \n"); //$NON-NLS-1$ + writer.write("}; \n"); //$NON-NLS-1$ + writer.write("struct v2 { \n"); //$NON-NLS-1$ + writer.write(" int v; \n"); //$NON-NLS-1$ + writer.write("}; \n"); //$NON-NLS-1$ + writer.write("struct v3 { \n"); //$NON-NLS-1$ + writer.write(" int v; \n"); //$NON-NLS-1$ + writer.write("}; \n"); //$NON-NLS-1$ + writer.write("int v4::function(){} \n"); //$NON-NLS-1$ + writer.write("void f(int par1){ \n"); //$NON-NLS-1$ + writer.write(" { \n"); //$NON-NLS-1$ + writer.write(" int w1; v1::v++; \n"); //$NON-NLS-1$ + writer.write(" } \n"); //$NON-NLS-1$ + writer.write("} \n"); //$NON-NLS-1$ + writer.write("void class_def::method(int par2) { \n"); //$NON-NLS-1$ + writer.write(" { \n"); //$NON-NLS-1$ + writer.write(" int w2; v2::v++; \n"); //$NON-NLS-1$ + writer.write(" } \n"); //$NON-NLS-1$ + writer.write("} \n"); //$NON-NLS-1$ + writer.write("static void class_def::static_method(int par3) { \n"); //$NON-NLS-1$ + writer.write(" { \n"); //$NON-NLS-1$ + writer.write(" int w3; v3::v++; \n"); //$NON-NLS-1$ + writer.write(" } \n"); //$NON-NLS-1$ + writer.write("} \n"); //$NON-NLS-1$ + String contents = writer.toString(); + IFile cpp= importFile("test.cpp", contents ); //$NON-NLS-1$ + + int offset1= contents.indexOf("v1"); //$NON-NLS-1$ + int offset2= contents.indexOf("v2"); //$NON-NLS-1$ + int offset3= contents.indexOf("v3"); //$NON-NLS-1$ + int offset4= contents.indexOf("v4"); //$NON-NLS-1$ + + // conflicting renamings + RefactoringStatus status= checkConditions(cpp, offset1, "w1"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, contents.indexOf("par1"), "v1"); //$NON-NLS-1$ //$NON-NLS-2$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "par1"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "extern_var"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "var_def"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "enum_item"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset2, "w2"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset2, "par2"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset2, "extern_var"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset2, "var_def"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset2, "enum_item"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset3, "w3"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset3, "par3"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset3, "extern_var"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset3, "var_def"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset3, "enum_item"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset4, "extern_var"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset4, "var_def"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset4, "enum_item"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "member"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "method"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "static_member"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "static_method"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset2, "member"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset2, "method"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset2, "static_member"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset2, "static_method"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset3, "static_member"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset3, "static_method"); //$NON-NLS-1$ + assertRefactoringOk(status); + + // renamings conflicting with global stuff. + status= checkConditions(cpp, offset1, "func_proto"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "func_proto_ov"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "func_def"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "func_def_ov"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset2, "func_proto"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset2, "func_proto_ov"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset2, "func_def"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset2, "func_def_ov"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset3, "func_proto"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset3, "func_proto_ov"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset3, "func_def"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset3, "func_def_ov"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset4, "func_proto"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset4, "func_proto_ov"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset4, "func_def"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset4, "func_def_ov"); //$NON-NLS-1$ + assertRefactoringOk(status); + + // renamings colliding with types. + status= checkConditions(cpp, offset1, "class_fwd"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: class_fwd \n" + + "Conflicting element type: Type"); //$NON-NLS-1$ + status= checkConditions(cpp, offset1, "struct_fwd"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: struct_fwd \n" + + "Conflicting element type: Type"); //$NON-NLS-1$ + status= checkConditions(cpp, offset1, "union_fwd"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: union_fwd \n" + + "Conflicting element type: Type"); //$NON-NLS-1$ + status= checkConditions(cpp, offset1, "class_def"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: class_def \n" + + "Conflicting element type: Type"); //$NON-NLS-1$ + status= checkConditions(cpp, offset1, "struct_def"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: struct_def \n" + + "Conflicting element type: Type"); //$NON-NLS-1$ + status= checkConditions(cpp, offset1, "union_def"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: union_def \n" + + "Conflicting element type: Type"); //$NON-NLS-1$ + status= checkConditions(cpp, offset1, "enum_def"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: enum_def \n" + + "Conflicting element type: Type"); //$NON-NLS-1$ + status= checkConditions(cpp, offset1, "typedef_def"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: typedef_def \n" + + "Conflicting element type: Type"); //$NON-NLS-1$ + status= checkConditions(cpp, offset1, "namespace_def"); //$NON-NLS-1$ + assertRefactoringWarning(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: namespace_def \n" + + "Conflicting element type: Namespace"); //$NON-NLS-1$ + status= checkConditions(cpp, offset1, "st_member"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "un_member"); //$NON-NLS-1$ + assertRefactoringOk(status); + + status= checkConditions(cpp, offset2, "class_fwd"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: class_fwd \n" + + "Conflicting element type: Type"); //$NON-NLS-1$ + status= checkConditions(cpp, offset2, "struct_fwd"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: struct_fwd \n" + + "Conflicting element type: Type"); //$NON-NLS-1$ + status= checkConditions(cpp, offset2, "union_fwd"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: union_fwd \n" + + "Conflicting element type: Type"); //$NON-NLS-1$ + status= checkConditions(cpp, offset2, "class_def"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: class_def \n" + + "Conflicting element type: Type"); //$NON-NLS-1$ + status= checkConditions(cpp, offset2, "struct_def"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: struct_def \n" + + "Conflicting element type: Type"); //$NON-NLS-1$ + status= checkConditions(cpp, offset2, "union_def"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: union_def \n" + + "Conflicting element type: Type"); //$NON-NLS-1$ + status= checkConditions(cpp, offset2, "enum_def"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: enum_def \n" + + "Conflicting element type: Type"); //$NON-NLS-1$ + status= checkConditions(cpp, offset2, "typedef_def"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: typedef_def \n" + + "Conflicting element type: Type"); //$NON-NLS-1$ + status= checkConditions(cpp, offset2, "namespace_def"); //$NON-NLS-1$ + assertRefactoringWarning(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: namespace_def \n" + + "Conflicting element type: Namespace"); //$NON-NLS-1$ + status= checkConditions(cpp, offset2, "st_member"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset2, "un_member"); //$NON-NLS-1$ + assertRefactoringOk(status); + + status= checkConditions(cpp, offset3, "class_fwd"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: class_fwd \n" + + "Conflicting element type: Type"); //$NON-NLS-1$ + status= checkConditions(cpp, offset3, "struct_fwd"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: struct_fwd \n" + + "Conflicting element type: Type"); //$NON-NLS-1$ + status= checkConditions(cpp, offset3, "union_fwd"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: union_fwd \n" + + "Conflicting element type: Type"); //$NON-NLS-1$ + status= checkConditions(cpp, offset3, "class_def"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: class_def \n" + + "Conflicting element type: Type"); //$NON-NLS-1$ + status= checkConditions(cpp, offset3, "struct_def"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: struct_def \n" + + "Conflicting element type: Type"); //$NON-NLS-1$ + status= checkConditions(cpp, offset3, "union_def"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: union_def \n" + + "Conflicting element type: Type"); //$NON-NLS-1$ + status= checkConditions(cpp, offset3, "enum_def"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: enum_def \n" + + "Conflicting element type: Type"); //$NON-NLS-1$ + status= checkConditions(cpp, offset3, "typedef_def"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: typedef_def \n" + + "Conflicting element type: Type"); //$NON-NLS-1$ + status= checkConditions(cpp, offset3, "namespace_def"); //$NON-NLS-1$ + assertRefactoringWarning(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: namespace_def \n" + + "Conflicting element type: Namespace"); //$NON-NLS-1$ + status= checkConditions(cpp, offset3, "st_member"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset3, "un_member"); //$NON-NLS-1$ + assertRefactoringOk(status); + + status= checkConditions(cpp, offset4, "class_fwd"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: class_fwd \n" + + "Conflicting element type: Type"); //$NON-NLS-1$ + status= checkConditions(cpp, offset4, "struct_fwd"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: struct_fwd \n" + + "Conflicting element type: Type"); //$NON-NLS-1$ + status= checkConditions(cpp, offset4, "union_fwd"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: union_fwd \n" + + "Conflicting element type: Type"); //$NON-NLS-1$ + status= checkConditions(cpp, offset4, "class_def"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: class_def \n" + + "Conflicting element type: Type"); //$NON-NLS-1$ + status= checkConditions(cpp, offset4, "struct_def"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: struct_def \n" + + "Conflicting element type: Type"); //$NON-NLS-1$ + status= checkConditions(cpp, offset4, "union_def"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: union_def \n" + + "Conflicting element type: Type"); //$NON-NLS-1$ + status= checkConditions(cpp, offset4, "enum_def"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: enum_def \n" + + "Conflicting element type: Type"); //$NON-NLS-1$ + status= checkConditions(cpp, offset4, "typedef_def"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: typedef_def \n" + + "Conflicting element type: Type"); //$NON-NLS-1$ + status= checkConditions(cpp, offset4, "namespace_def"); //$NON-NLS-1$ + assertRefactoringWarning(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: namespace_def \n" + + "Conflicting element type: Namespace"); //$NON-NLS-1$ + status= checkConditions(cpp, offset4, "st_member"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset4, "un_member"); //$NON-NLS-1$ + assertRefactoringOk(status); + } + + public void testStructNameConflictsPlainC() throws Exception { + createCFwdDecls("c_fwd.h"); //$NON-NLS-1$ + createCDefs("c_def.h"); //$NON-NLS-1$ + StringWriter writer = new StringWriter(); + writer.write("#include \"c_fwd.h\" \n"); //$NON-NLS-1$ + writer.write("#include \"c_def.h\" \n"); //$NON-NLS-1$ + writer.write("struct v1 { \n"); //$NON-NLS-1$ + writer.write(" int v; \n"); //$NON-NLS-1$ + writer.write("}; \n"); //$NON-NLS-1$ + writer.write("struct v2 { \n"); //$NON-NLS-1$ + writer.write(" int v; \n"); //$NON-NLS-1$ + writer.write("}; \n"); //$NON-NLS-1$ + writer.write("struct v3 { \n"); //$NON-NLS-1$ + writer.write(" int v; \n"); //$NON-NLS-1$ + writer.write("}; \n"); //$NON-NLS-1$ + writer.write("void f(int par1){ \n"); //$NON-NLS-1$ + writer.write(" { \n"); //$NON-NLS-1$ + writer.write(" int w1; v1::v++; \n"); //$NON-NLS-1$ + writer.write(" } \n"); //$NON-NLS-1$ + writer.write("} \n"); //$NON-NLS-1$ + String contents = writer.toString(); + IFile cpp= importFile("test.cpp", contents ); //$NON-NLS-1$ + + int offset1= contents.indexOf("v1"); //$NON-NLS-1$ + + // conflicting renamings + RefactoringStatus status= checkConditions(cpp, offset1, "w1"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, contents.indexOf("par1"), "v1"); //$NON-NLS-1$ //$NON-NLS-2$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "par1"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "extern_var"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "var_def"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "enum_item"); //$NON-NLS-1$ + assertRefactoringOk(status); + + // renamings conflicting with global stuff. + status= checkConditions(cpp, offset1, "func_proto"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "func_def"); //$NON-NLS-1$ + assertRefactoringOk(status); + + // renamings colliding with types. + status= checkConditions(cpp, offset1, "struct_fwd"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: struct_fwd \n" + + "Conflicting element type: Type"); //$NON-NLS-1$ + status= checkConditions(cpp, offset1, "union_fwd"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: union_fwd \n" + + "Conflicting element type: Type"); //$NON-NLS-1$ + status= checkConditions(cpp, offset1, "struct_def"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: struct_def \n" + + "Conflicting element type: Type"); //$NON-NLS-1$ + status= checkConditions(cpp, offset1, "union_def"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: union_def \n" + + "Conflicting element type: Type"); //$NON-NLS-1$ + status= checkConditions(cpp, offset1, "enum_def"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: enum_def \n" + + "Conflicting element type: Type"); //$NON-NLS-1$ + status= checkConditions(cpp, offset1, "typedef_def"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: typedef_def \n" + + "Conflicting element type: Type"); //$NON-NLS-1$ + status= checkConditions(cpp, offset1, "st_member"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "un_member"); //$NON-NLS-1$ + assertRefactoringOk(status); + + } + + public void testUnionNameConflicts() throws Exception { + createCppFwdDecls("cpp_fwd.hh"); //$NON-NLS-1$ + createCppDefs("cpp_def.hh"); //$NON-NLS-1$ + StringWriter writer = new StringWriter(); + writer.write("#include \"cpp_fwd.hh\" \n"); //$NON-NLS-1$ + writer.write("#include \"cpp_def.hh\" \n"); //$NON-NLS-1$ + writer.write("union v4 { \n"); //$NON-NLS-1$ + writer.write(" int function(); \n"); //$NON-NLS-1$ + writer.write("}; \n"); //$NON-NLS-1$ + writer.write("union v1 { \n"); //$NON-NLS-1$ + writer.write(" int v; \n"); //$NON-NLS-1$ + writer.write("}; \n"); //$NON-NLS-1$ + writer.write("union v2 { \n"); //$NON-NLS-1$ + writer.write(" int v; \n"); //$NON-NLS-1$ + writer.write("}; \n"); //$NON-NLS-1$ + writer.write("union v3 { \n"); //$NON-NLS-1$ + writer.write(" int v; \n"); //$NON-NLS-1$ + writer.write("}; \n"); //$NON-NLS-1$ + writer.write("int v4::function(){} \n"); //$NON-NLS-1$ + writer.write("void f(int par1){ \n"); //$NON-NLS-1$ + writer.write(" { \n"); //$NON-NLS-1$ + writer.write(" int w1; v1::v++; \n"); //$NON-NLS-1$ + writer.write(" } \n"); //$NON-NLS-1$ + writer.write("} \n"); //$NON-NLS-1$ + writer.write("void class_def::method(int par2) { \n"); //$NON-NLS-1$ + writer.write(" { \n"); //$NON-NLS-1$ + writer.write(" int w2; v2::v++; \n"); //$NON-NLS-1$ + writer.write(" } \n"); //$NON-NLS-1$ + writer.write("} \n"); //$NON-NLS-1$ + writer.write("static void class_def::static_method(int par3) { \n"); //$NON-NLS-1$ + writer.write(" { \n"); //$NON-NLS-1$ + writer.write(" int w3; v3::v++; \n"); //$NON-NLS-1$ + writer.write(" } \n"); //$NON-NLS-1$ + writer.write("} \n"); //$NON-NLS-1$ + String contents = writer.toString(); + IFile cpp= importFile("test.cpp", contents ); //$NON-NLS-1$ + + int offset1= contents.indexOf("v1"); //$NON-NLS-1$ + int offset2= contents.indexOf("v2"); //$NON-NLS-1$ + int offset3= contents.indexOf("v3"); //$NON-NLS-1$ + int offset4= contents.indexOf("v4"); //$NON-NLS-1$ + + // conflicting renamings + RefactoringStatus status= checkConditions(cpp, offset1, "w1"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, contents.indexOf("par1"), "v1"); //$NON-NLS-1$ //$NON-NLS-2$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "par1"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "extern_var"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "var_def"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "enum_item"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset2, "w2"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset2, "par2"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset2, "extern_var"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset2, "var_def"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset2, "enum_item"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset3, "w3"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset3, "par3"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset3, "extern_var"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset3, "var_def"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset3, "enum_item"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset4, "extern_var"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset4, "var_def"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset4, "enum_item"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "member"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "method"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "static_member"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "static_method"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset2, "member"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset2, "method"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset2, "static_member"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset2, "static_method"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset3, "static_member"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset3, "static_method"); //$NON-NLS-1$ + assertRefactoringOk(status); + + // renamings conflicting with global stuff. + status= checkConditions(cpp, offset1, "func_proto"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "func_proto_ov"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "func_def"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "func_def_ov"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset2, "func_proto"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset2, "func_proto_ov"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset2, "func_def"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset2, "func_def_ov"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset3, "func_proto"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset3, "func_proto_ov"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset3, "func_def"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset3, "func_def_ov"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset4, "func_proto"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset4, "func_proto_ov"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset4, "func_def"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset4, "func_def_ov"); //$NON-NLS-1$ + assertRefactoringOk(status); + + // renamings colliding with types. + status= checkConditions(cpp, offset1, "class_fwd"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: class_fwd \n" + + "Conflicting element type: Type"); //$NON-NLS-1$ + status= checkConditions(cpp, offset1, "struct_fwd"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: struct_fwd \n" + + "Conflicting element type: Type"); //$NON-NLS-1$ + status= checkConditions(cpp, offset1, "union_fwd"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: union_fwd \n" + + "Conflicting element type: Type"); //$NON-NLS-1$ + status= checkConditions(cpp, offset1, "class_def"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: class_def \n" + + "Conflicting element type: Type"); //$NON-NLS-1$ + status= checkConditions(cpp, offset1, "struct_def"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: struct_def \n" + + "Conflicting element type: Type"); //$NON-NLS-1$ + status= checkConditions(cpp, offset1, "union_def"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: union_def \n" + + "Conflicting element type: Type"); //$NON-NLS-1$ + status= checkConditions(cpp, offset1, "enum_def"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: enum_def \n" + + "Conflicting element type: Type"); //$NON-NLS-1$ + status= checkConditions(cpp, offset1, "typedef_def"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: typedef_def \n" + + "Conflicting element type: Type"); //$NON-NLS-1$ + status= checkConditions(cpp, offset1, "namespace_def"); //$NON-NLS-1$ + assertRefactoringWarning(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: namespace_def \n" + + "Conflicting element type: Namespace"); //$NON-NLS-1$ + status= checkConditions(cpp, offset1, "st_member"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "un_member"); //$NON-NLS-1$ + assertRefactoringOk(status); + + status= checkConditions(cpp, offset2, "class_fwd"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: class_fwd \n" + + "Conflicting element type: Type"); //$NON-NLS-1$ + status= checkConditions(cpp, offset2, "struct_fwd"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: struct_fwd \n" + + "Conflicting element type: Type"); //$NON-NLS-1$ + status= checkConditions(cpp, offset2, "union_fwd"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: union_fwd \n" + + "Conflicting element type: Type"); //$NON-NLS-1$ + status= checkConditions(cpp, offset2, "class_def"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: class_def \n" + + "Conflicting element type: Type"); //$NON-NLS-1$ + status= checkConditions(cpp, offset2, "struct_def"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: struct_def \n" + + "Conflicting element type: Type"); //$NON-NLS-1$ + status= checkConditions(cpp, offset2, "union_def"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: union_def \n" + + "Conflicting element type: Type"); //$NON-NLS-1$ + status= checkConditions(cpp, offset2, "enum_def"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: enum_def \n" + + "Conflicting element type: Type"); //$NON-NLS-1$ + status= checkConditions(cpp, offset2, "typedef_def"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: typedef_def \n" + + "Conflicting element type: Type"); //$NON-NLS-1$ + status= checkConditions(cpp, offset2, "namespace_def"); //$NON-NLS-1$ + assertRefactoringWarning(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: namespace_def \n" + + "Conflicting element type: Namespace"); //$NON-NLS-1$ + status= checkConditions(cpp, offset2, "st_member"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset2, "un_member"); //$NON-NLS-1$ + assertRefactoringOk(status); + + status= checkConditions(cpp, offset3, "class_fwd"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: class_fwd \n" + + "Conflicting element type: Type"); //$NON-NLS-1$ + status= checkConditions(cpp, offset3, "struct_fwd"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: struct_fwd \n" + + "Conflicting element type: Type"); //$NON-NLS-1$ + status= checkConditions(cpp, offset3, "union_fwd"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: union_fwd \n" + + "Conflicting element type: Type"); //$NON-NLS-1$ + status= checkConditions(cpp, offset3, "class_def"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: class_def \n" + + "Conflicting element type: Type"); //$NON-NLS-1$ + status= checkConditions(cpp, offset3, "struct_def"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: struct_def \n" + + "Conflicting element type: Type"); //$NON-NLS-1$ + status= checkConditions(cpp, offset3, "union_def"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: union_def \n" + + "Conflicting element type: Type"); //$NON-NLS-1$ + status= checkConditions(cpp, offset3, "enum_def"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: enum_def \n" + + "Conflicting element type: Type"); //$NON-NLS-1$ + status= checkConditions(cpp, offset3, "typedef_def"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: typedef_def \n" + + "Conflicting element type: Type"); //$NON-NLS-1$ + status= checkConditions(cpp, offset3, "namespace_def"); //$NON-NLS-1$ + assertRefactoringWarning(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: namespace_def \n" + + "Conflicting element type: Namespace"); //$NON-NLS-1$ + status= checkConditions(cpp, offset3, "st_member"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset3, "un_member"); //$NON-NLS-1$ + assertRefactoringOk(status); + + status= checkConditions(cpp, offset4, "class_fwd"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: class_fwd \n" + + "Conflicting element type: Type"); //$NON-NLS-1$ + status= checkConditions(cpp, offset4, "struct_fwd"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: struct_fwd \n" + + "Conflicting element type: Type"); //$NON-NLS-1$ + status= checkConditions(cpp, offset4, "union_fwd"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: union_fwd \n" + + "Conflicting element type: Type"); //$NON-NLS-1$ + status= checkConditions(cpp, offset4, "class_def"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: class_def \n" + + "Conflicting element type: Type"); //$NON-NLS-1$ + status= checkConditions(cpp, offset4, "struct_def"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: struct_def \n" + + "Conflicting element type: Type"); //$NON-NLS-1$ + status= checkConditions(cpp, offset4, "union_def"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: union_def \n" + + "Conflicting element type: Type"); //$NON-NLS-1$ + status= checkConditions(cpp, offset4, "enum_def"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: enum_def \n" + + "Conflicting element type: Type"); //$NON-NLS-1$ + status= checkConditions(cpp, offset4, "typedef_def"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: typedef_def \n" + + "Conflicting element type: Type"); //$NON-NLS-1$ + status= checkConditions(cpp, offset4, "namespace_def"); //$NON-NLS-1$ + assertRefactoringWarning(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: namespace_def \n" + + "Conflicting element type: Namespace"); //$NON-NLS-1$ + status= checkConditions(cpp, offset4, "st_member"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset4, "un_member"); //$NON-NLS-1$ + assertRefactoringOk(status); + } + + public void testUnionNameConflictsPlainC() throws Exception { + createCFwdDecls("c_fwd.h"); //$NON-NLS-1$ + createCDefs("c_def.h"); //$NON-NLS-1$ + StringWriter writer = new StringWriter(); + writer.write("#include \"c_fwd.h\" \n"); //$NON-NLS-1$ + writer.write("#include \"c_def.h\" \n"); //$NON-NLS-1$ + writer.write("union v1 { \n"); //$NON-NLS-1$ + writer.write(" int v; \n"); //$NON-NLS-1$ + writer.write("}; \n"); //$NON-NLS-1$ + writer.write("union v1 vv1; \n"); //$NON-NLS-1$ + writer.write("void f(int par1){ \n"); //$NON-NLS-1$ + writer.write(" int w1; vv1.v++; \n"); //$NON-NLS-1$ + writer.write("} \n"); //$NON-NLS-1$ + String contents = writer.toString(); + IFile cpp= importFile("test.c", contents ); //$NON-NLS-1$ + + int offset1= contents.indexOf("v1"); //$NON-NLS-1$ + + // conflicting renamings + RefactoringStatus status= checkConditions(cpp, offset1, "w1"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, contents.indexOf("par1"), "v1"); //$NON-NLS-1$ //$NON-NLS-2$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "par1"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "extern_var"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "var_def"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "enum_item"); //$NON-NLS-1$ + assertRefactoringOk(status); + + // renamings conflicting with global stuff. + status= checkConditions(cpp, offset1, "func_proto"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "func_def"); //$NON-NLS-1$ + assertRefactoringOk(status); + + // renamings colliding with types. + status= checkConditions(cpp, offset1, "struct_fwd"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: struct_fwd \n" + + "Conflicting element type: Type"); //$NON-NLS-1$ + status= checkConditions(cpp, offset1, "union_fwd"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: union_fwd \n" + + "Conflicting element type: Type"); //$NON-NLS-1$ + status= checkConditions(cpp, offset1, "struct_def"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: struct_def \n" + + "Conflicting element type: Type"); //$NON-NLS-1$ + status= checkConditions(cpp, offset1, "union_def"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: union_def \n" + + "Conflicting element type: Type"); //$NON-NLS-1$ + status= checkConditions(cpp, offset1, "enum_def"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: enum_def \n" + + "Conflicting element type: Type"); //$NON-NLS-1$ + status= checkConditions(cpp, offset1, "typedef_def"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: typedef_def \n" + + "Conflicting element type: Type"); //$NON-NLS-1$ + status= checkConditions(cpp, offset1, "st_member"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "un_member"); //$NON-NLS-1$ + assertRefactoringOk(status); + + } + + public void testEnumNameConflicts() throws Exception { + createCppFwdDecls("cpp_fwd.hh"); //$NON-NLS-1$ + createCppDefs("cpp_def.hh"); //$NON-NLS-1$ + StringWriter writer = new StringWriter(); + writer.write("#include \"cpp_fwd.hh\" \n"); //$NON-NLS-1$ + writer.write("#include \"cpp_def.hh\" \n"); //$NON-NLS-1$ + writer.write("enum v1 { \n"); //$NON-NLS-1$ + writer.write(" v11 \n"); //$NON-NLS-1$ + writer.write("}; \n"); //$NON-NLS-1$ + writer.write("enum v2 { \n"); //$NON-NLS-1$ + writer.write(" v22 \n"); //$NON-NLS-1$ + writer.write("}; \n"); //$NON-NLS-1$ + writer.write("enum v3 { \n"); //$NON-NLS-1$ + writer.write(" v33 \n"); //$NON-NLS-1$ + writer.write("}; \n"); //$NON-NLS-1$ + writer.write("void f(int par1){ \n"); //$NON-NLS-1$ + writer.write(" int w1; v1 v; \n"); //$NON-NLS-1$ + writer.write("} \n"); //$NON-NLS-1$ + writer.write("void class_def::method(int par2) { \n"); //$NON-NLS-1$ + writer.write(" int w2; v2 v; \n"); //$NON-NLS-1$ + writer.write("} \n"); //$NON-NLS-1$ + writer.write("static void class_def::static_method(int par3) { \n"); //$NON-NLS-1$ + writer.write(" int w3; v3 v; \n"); //$NON-NLS-1$ + writer.write("} \n"); //$NON-NLS-1$ + String contents = writer.toString(); + IFile cpp= importFile("test.cpp", contents ); //$NON-NLS-1$ + + int offset1= contents.indexOf("v1"); //$NON-NLS-1$ + int offset2= contents.indexOf("v2"); //$NON-NLS-1$ + int offset3= contents.indexOf("v3"); //$NON-NLS-1$ + + // conflicting renamings + RefactoringStatus status= checkConditions(cpp, offset1, "w1"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, contents.indexOf("par1"), "v1"); //$NON-NLS-1$ //$NON-NLS-2$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "par1"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "extern_var"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "var_def"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "enum_item"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset2, "w2"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset2, "par2"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset2, "extern_var"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset2, "var_def"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset2, "enum_item"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset3, "w3"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset3, "par3"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset3, "extern_var"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset3, "var_def"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset3, "enum_item"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "member"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "method"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "static_member"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "static_method"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset2, "member"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset2, "method"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset2, "static_member"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset2, "static_method"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset3, "static_member"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset3, "static_method"); //$NON-NLS-1$ + assertRefactoringOk(status); + + // renamings conflicting with global stuff. + status= checkConditions(cpp, offset1, "func_proto"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "func_proto_ov"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "func_def"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "func_def_ov"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset2, "func_proto"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset2, "func_proto_ov"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset2, "func_def"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset2, "func_def_ov"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset3, "func_proto"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset3, "func_proto_ov"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset3, "func_def"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset3, "func_def_ov"); //$NON-NLS-1$ + assertRefactoringOk(status); + + // renamings colliding with types. + status= checkConditions(cpp, offset1, "class_fwd"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: class_fwd \n" + + "Conflicting element type: Type"); //$NON-NLS-1$ + status= checkConditions(cpp, offset1, "struct_fwd"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: struct_fwd \n" + + "Conflicting element type: Type"); //$NON-NLS-1$ + status= checkConditions(cpp, offset1, "union_fwd"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: union_fwd \n" + + "Conflicting element type: Type"); //$NON-NLS-1$ + status= checkConditions(cpp, offset1, "class_def"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: class_def \n" + + "Conflicting element type: Type"); //$NON-NLS-1$ + status= checkConditions(cpp, offset1, "struct_def"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: struct_def \n" + + "Conflicting element type: Type"); //$NON-NLS-1$ + status= checkConditions(cpp, offset1, "union_def"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: union_def \n" + + "Conflicting element type: Type"); //$NON-NLS-1$ + status= checkConditions(cpp, offset1, "enum_def"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: enum_def \n" + + "Conflicting element type: Type"); //$NON-NLS-1$ + status= checkConditions(cpp, offset1, "typedef_def"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: typedef_def \n" + + "Conflicting element type: Type"); //$NON-NLS-1$ + status= checkConditions(cpp, offset1, "namespace_def"); //$NON-NLS-1$ + assertRefactoringWarning(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: namespace_def \n" + + "Conflicting element type: Namespace"); //$NON-NLS-1$ + status= checkConditions(cpp, offset1, "st_member"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "un_member"); //$NON-NLS-1$ + assertRefactoringOk(status); + + status= checkConditions(cpp, offset2, "class_fwd"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: class_fwd \n" + + "Conflicting element type: Type"); //$NON-NLS-1$ + status= checkConditions(cpp, offset2, "struct_fwd"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: struct_fwd \n" + + "Conflicting element type: Type"); //$NON-NLS-1$ + status= checkConditions(cpp, offset2, "union_fwd"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: union_fwd \n" + + "Conflicting element type: Type"); //$NON-NLS-1$ + status= checkConditions(cpp, offset2, "class_def"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: class_def \n" + + "Conflicting element type: Type"); //$NON-NLS-1$ + status= checkConditions(cpp, offset2, "struct_def"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: struct_def \n" + + "Conflicting element type: Type"); //$NON-NLS-1$ + status= checkConditions(cpp, offset2, "union_def"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: union_def \n" + + "Conflicting element type: Type"); //$NON-NLS-1$ + status= checkConditions(cpp, offset2, "enum_def"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: enum_def \n" + + "Conflicting element type: Type"); //$NON-NLS-1$ + status= checkConditions(cpp, offset2, "typedef_def"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: typedef_def \n" + + "Conflicting element type: Type"); //$NON-NLS-1$ + status= checkConditions(cpp, offset2, "namespace_def"); //$NON-NLS-1$ + assertRefactoringWarning(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: namespace_def \n" + + "Conflicting element type: Namespace"); //$NON-NLS-1$ + status= checkConditions(cpp, offset2, "st_member"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset2, "un_member"); //$NON-NLS-1$ + assertRefactoringOk(status); + + status= checkConditions(cpp, offset3, "class_fwd"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: class_fwd \n" + + "Conflicting element type: Type"); //$NON-NLS-1$ + status= checkConditions(cpp, offset3, "struct_fwd"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: struct_fwd \n" + + "Conflicting element type: Type"); //$NON-NLS-1$ + status= checkConditions(cpp, offset3, "union_fwd"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: union_fwd \n" + + "Conflicting element type: Type"); //$NON-NLS-1$ + status= checkConditions(cpp, offset3, "class_def"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: class_def \n" + + "Conflicting element type: Type"); //$NON-NLS-1$ + status= checkConditions(cpp, offset3, "struct_def"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: struct_def \n" + + "Conflicting element type: Type"); //$NON-NLS-1$ + status= checkConditions(cpp, offset3, "union_def"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: union_def \n" + + "Conflicting element type: Type"); //$NON-NLS-1$ + status= checkConditions(cpp, offset3, "enum_def"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: enum_def \n" + + "Conflicting element type: Type"); //$NON-NLS-1$ + status= checkConditions(cpp, offset3, "typedef_def"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: typedef_def \n" + + "Conflicting element type: Type"); //$NON-NLS-1$ + status= checkConditions(cpp, offset3, "namespace_def"); //$NON-NLS-1$ + assertRefactoringWarning(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: namespace_def \n" + + "Conflicting element type: Namespace"); //$NON-NLS-1$ + status= checkConditions(cpp, offset3, "st_member"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset3, "un_member"); //$NON-NLS-1$ + assertRefactoringOk(status); + } + + public void testEnumNameConflictsPlainC() throws Exception { + createCppFwdDecls("c_fwd.h"); //$NON-NLS-1$ + createCppDefs("c_def.h"); //$NON-NLS-1$ + StringWriter writer = new StringWriter(); + writer.write("#include \"c_fwd.h\" \n"); //$NON-NLS-1$ + writer.write("#include \"c_def.h\" \n"); //$NON-NLS-1$ + writer.write("enum v1 { \n"); //$NON-NLS-1$ + writer.write(" v11 \n"); //$NON-NLS-1$ + writer.write("}; \n"); //$NON-NLS-1$ + writer.write("enum v2 { \n"); //$NON-NLS-1$ + writer.write(" v22 \n"); //$NON-NLS-1$ + writer.write("}; \n"); //$NON-NLS-1$ + writer.write("enum v3 { \n"); //$NON-NLS-1$ + writer.write(" v33 \n"); //$NON-NLS-1$ + writer.write("}; \n"); //$NON-NLS-1$ + writer.write("void f(int par1){ \n"); //$NON-NLS-1$ + writer.write(" int w1; enum v1 v; \n"); //$NON-NLS-1$ + writer.write("} \n"); //$NON-NLS-1$ + String contents = writer.toString(); + IFile cpp= importFile("test.c", contents ); //$NON-NLS-1$ + + int offset1= contents.indexOf("v1"); //$NON-NLS-1$ + + // conflicting renamings + RefactoringStatus status= checkConditions(cpp, offset1, "w1"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, contents.indexOf("par1"), "v1"); //$NON-NLS-1$ //$NON-NLS-2$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "par1"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "extern_var"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "var_def"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "enum_item"); //$NON-NLS-1$ + assertRefactoringOk(status); + + // renamings conflicting with global stuff. + status= checkConditions(cpp, offset1, "func_proto"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "func_proto_ov"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "func_def"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "func_def_ov"); //$NON-NLS-1$ + assertRefactoringOk(status); + + // renamings colliding with types. + status= checkConditions(cpp, offset1, "struct_fwd"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: struct_fwd \n" + + "Conflicting element type: Type"); //$NON-NLS-1$ + status= checkConditions(cpp, offset1, "union_fwd"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: union_fwd \n" + + "Conflicting element type: Type"); //$NON-NLS-1$ + status= checkConditions(cpp, offset1, "struct_def"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: struct_def \n" + + "Conflicting element type: Type"); //$NON-NLS-1$ + status= checkConditions(cpp, offset1, "union_def"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: union_def \n" + + "Conflicting element type: Type"); //$NON-NLS-1$ + status= checkConditions(cpp, offset1, "enum_def"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: enum_def \n" + + "Conflicting element type: Type"); //$NON-NLS-1$ + status= checkConditions(cpp, offset1, "typedef_def"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: typedef_def \n" + + "Conflicting element type: Type"); //$NON-NLS-1$ + status= checkConditions(cpp, offset1, "st_member"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "un_member"); //$NON-NLS-1$ + assertRefactoringOk(status); + } + + public void testTypedefNameConflicts() throws Exception { + createCppFwdDecls("cpp_fwd.hh"); //$NON-NLS-1$ + createCppDefs("cpp_def.hh"); //$NON-NLS-1$ + StringWriter writer = new StringWriter(); + writer.write("#include \"cpp_fwd.hh\" \n"); //$NON-NLS-1$ + writer.write("#include \"cpp_def.hh\" \n"); //$NON-NLS-1$ + writer.write("typedef int v1; \n"); //$NON-NLS-1$ + writer.write("typedef long v2; \n"); //$NON-NLS-1$ + writer.write("typedef struct {int a;} v3; \n"); //$NON-NLS-1$ + writer.write("void f(int par1){ \n"); //$NON-NLS-1$ + writer.write(" int w1; v1 v; \n"); //$NON-NLS-1$ + writer.write("} \n"); //$NON-NLS-1$ + writer.write("void class_def::method(int par2) { \n"); //$NON-NLS-1$ + writer.write(" { \n"); //$NON-NLS-1$ + writer.write(" int w2; v2 v; \n"); //$NON-NLS-1$ + writer.write(" } \n"); //$NON-NLS-1$ + writer.write("} \n"); //$NON-NLS-1$ + writer.write("static void class_def::static_method(int par3) { \n"); //$NON-NLS-1$ + writer.write(" { \n"); //$NON-NLS-1$ + writer.write(" int w3; v3 v; \n"); //$NON-NLS-1$ + writer.write(" } \n"); //$NON-NLS-1$ + writer.write("} \n"); //$NON-NLS-1$ + String contents = writer.toString(); + IFile cpp= importFile("test.cpp", contents ); //$NON-NLS-1$ + + int offset1= contents.indexOf("v1"); //$NON-NLS-1$ + int offset2= contents.indexOf("v2"); //$NON-NLS-1$ + int offset3= contents.indexOf("v3"); //$NON-NLS-1$ + + // conflicting renamings + RefactoringStatus status= checkConditions(cpp, offset1, "w1"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, contents.indexOf("par1"), "v1"); //$NON-NLS-1$ //$NON-NLS-2$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "par1"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "extern_var"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "var_def"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "enum_item"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset2, "w2"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset2, "par2"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset2, "extern_var"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset2, "var_def"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset2, "enum_item"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset3, "w3"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset3, "par3"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset3, "extern_var"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset3, "var_def"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset3, "enum_item"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "member"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "method"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "static_member"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "static_method"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset2, "member"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset2, "method"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset2, "static_member"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset2, "static_method"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset3, "static_member"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset3, "static_method"); //$NON-NLS-1$ + assertRefactoringOk(status); + + // renamings conflicting with global stuff. + status= checkConditions(cpp, offset1, "func_proto"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "func_proto_ov"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "func_def"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "func_def_ov"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset2, "func_proto"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset2, "func_proto_ov"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset2, "func_def"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset2, "func_def_ov"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset3, "func_proto"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset3, "func_proto_ov"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset3, "func_def"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset3, "func_def_ov"); //$NON-NLS-1$ + assertRefactoringOk(status); + + // renamings colliding with types. + status= checkConditions(cpp, offset1, "class_fwd"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: class_fwd \n" + + "Conflicting element type: Type"); //$NON-NLS-1$ + status= checkConditions(cpp, offset1, "struct_fwd"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: struct_fwd \n" + + "Conflicting element type: Type"); //$NON-NLS-1$ + status= checkConditions(cpp, offset1, "union_fwd"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: union_fwd \n" + + "Conflicting element type: Type"); //$NON-NLS-1$ + status= checkConditions(cpp, offset1, "class_def"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: class_def \n" + + "Conflicting element type: Type"); //$NON-NLS-1$ + status= checkConditions(cpp, offset1, "struct_def"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: struct_def \n" + + "Conflicting element type: Type"); //$NON-NLS-1$ + status= checkConditions(cpp, offset1, "union_def"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: union_def \n" + + "Conflicting element type: Type"); //$NON-NLS-1$ + status= checkConditions(cpp, offset1, "enum_def"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: enum_def \n" + + "Conflicting element type: Type"); //$NON-NLS-1$ + status= checkConditions(cpp, offset1, "typedef_def"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: typedef_def \n" + + "Conflicting element type: Type"); //$NON-NLS-1$ + status= checkConditions(cpp, offset1, "namespace_def"); //$NON-NLS-1$ + assertRefactoringWarning(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: namespace_def \n" + + "Conflicting element type: Namespace"); //$NON-NLS-1$ + status= checkConditions(cpp, offset1, "st_member"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "un_member"); //$NON-NLS-1$ + assertRefactoringOk(status); + + status= checkConditions(cpp, offset2, "class_fwd"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: class_fwd \n" + + "Conflicting element type: Type"); //$NON-NLS-1$ + status= checkConditions(cpp, offset2, "struct_fwd"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: struct_fwd \n" + + "Conflicting element type: Type"); //$NON-NLS-1$ + status= checkConditions(cpp, offset2, "union_fwd"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: union_fwd \n" + + "Conflicting element type: Type"); //$NON-NLS-1$ + status= checkConditions(cpp, offset2, "class_def"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: class_def \n" + + "Conflicting element type: Type"); //$NON-NLS-1$ + status= checkConditions(cpp, offset2, "struct_def"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: struct_def \n" + + "Conflicting element type: Type"); //$NON-NLS-1$ + status= checkConditions(cpp, offset2, "union_def"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: union_def \n" + + "Conflicting element type: Type"); //$NON-NLS-1$ + status= checkConditions(cpp, offset2, "enum_def"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: enum_def \n" + + "Conflicting element type: Type"); //$NON-NLS-1$ + status= checkConditions(cpp, offset2, "typedef_def"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: typedef_def \n" + + "Conflicting element type: Type"); //$NON-NLS-1$ + status= checkConditions(cpp, offset2, "namespace_def"); //$NON-NLS-1$ + assertRefactoringWarning(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: namespace_def \n" + + "Conflicting element type: Namespace"); //$NON-NLS-1$ + status= checkConditions(cpp, offset2, "st_member"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset2, "un_member"); //$NON-NLS-1$ + assertRefactoringOk(status); + + status= checkConditions(cpp, offset3, "class_fwd"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: class_fwd \n" + + "Conflicting element type: Type"); //$NON-NLS-1$ + status= checkConditions(cpp, offset3, "struct_fwd"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: struct_fwd \n" + + "Conflicting element type: Type"); //$NON-NLS-1$ + status= checkConditions(cpp, offset3, "union_fwd"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: union_fwd \n" + + "Conflicting element type: Type"); //$NON-NLS-1$ + status= checkConditions(cpp, offset3, "class_def"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: class_def \n" + + "Conflicting element type: Type"); //$NON-NLS-1$ + status= checkConditions(cpp, offset3, "struct_def"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: struct_def \n" + + "Conflicting element type: Type"); //$NON-NLS-1$ + status= checkConditions(cpp, offset3, "union_def"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: union_def \n" + + "Conflicting element type: Type"); //$NON-NLS-1$ + status= checkConditions(cpp, offset3, "enum_def"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: enum_def \n" + + "Conflicting element type: Type"); //$NON-NLS-1$ + status= checkConditions(cpp, offset3, "typedef_def"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: typedef_def \n" + + "Conflicting element type: Type"); //$NON-NLS-1$ + status= checkConditions(cpp, offset3, "namespace_def"); //$NON-NLS-1$ + assertRefactoringWarning(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: namespace_def \n" + + "Conflicting element type: Namespace"); //$NON-NLS-1$ + status= checkConditions(cpp, offset3, "st_member"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset3, "un_member"); //$NON-NLS-1$ + assertRefactoringOk(status); + } + + public void testTypedefNameConflictsPlainC() throws Exception { + createCFwdDecls("c_fwd.h"); //$NON-NLS-1$ + createCDefs("c_def.h"); //$NON-NLS-1$ + StringWriter writer = new StringWriter(); + writer.write("#include \"c_fwd.h\" \n"); //$NON-NLS-1$ + writer.write("#include \"c_def.h\" \n"); //$NON-NLS-1$ + writer.write("typedef int v1; \n"); //$NON-NLS-1$ + writer.write("typedef long v2; \n"); //$NON-NLS-1$ + writer.write("typedef struct {int a;} v3; \n"); //$NON-NLS-1$ + writer.write("void f(int par1){ \n"); //$NON-NLS-1$ + writer.write(" int w1; v1 v; \n"); //$NON-NLS-1$ + writer.write("} \n"); //$NON-NLS-1$ + String contents = writer.toString(); + IFile cpp= importFile("test.c", contents ); //$NON-NLS-1$ + + int offset1= contents.indexOf("v1"); //$NON-NLS-1$ + + // conflicting renamings + RefactoringStatus status= checkConditions(cpp, offset1, "w1"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, contents.indexOf("par1"), "v1"); //$NON-NLS-1$ //$NON-NLS-2$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "par1"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "extern_var"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "var_def"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "enum_item"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "member"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "method"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "static_member"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "static_method"); //$NON-NLS-1$ + assertRefactoringOk(status); + + // renamings conflicting with global stuff. + status= checkConditions(cpp, offset1, "func_proto"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "func_proto_ov"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "func_def"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "func_def_ov"); //$NON-NLS-1$ + assertRefactoringOk(status); + + // renamings colliding with types. + status= checkConditions(cpp, offset1, "struct_fwd"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: struct_fwd \n" + + "Conflicting element type: Type"); //$NON-NLS-1$ + status= checkConditions(cpp, offset1, "union_fwd"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: union_fwd \n" + + "Conflicting element type: Type"); //$NON-NLS-1$ + status= checkConditions(cpp, offset1, "struct_def"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: struct_def \n" + + "Conflicting element type: Type"); //$NON-NLS-1$ + status= checkConditions(cpp, offset1, "union_def"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: union_def \n" + + "Conflicting element type: Type"); //$NON-NLS-1$ + status= checkConditions(cpp, offset1, "enum_def"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: enum_def \n" + + "Conflicting element type: Type"); //$NON-NLS-1$ + status= checkConditions(cpp, offset1, "typedef_def"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: typedef_def \n" + + "Conflicting element type: Type"); //$NON-NLS-1$ + status= checkConditions(cpp, offset1, "st_member"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "un_member"); //$NON-NLS-1$ + assertRefactoringOk(status); + } + + public void testRenameClass() throws Exception { + StringWriter writer = new StringWriter(); + writer.write("class String \n"); //$NON-NLS-1$ + writer.write("{ \n"); //$NON-NLS-1$ + writer.write("public: \n"); //$NON-NLS-1$ + writer.write(" String(); \n"); //$NON-NLS-1$ + writer.write(" String(const String &other); \n"); //$NON-NLS-1$ + writer.write(" ~String(); \n"); //$NON-NLS-1$ + writer.write(" String &operator=( const String &other ); \n"); //$NON-NLS-1$ + writer.write("}; \n"); //$NON-NLS-1$ + writer.write(" String::String(){} \n"); //$NON-NLS-1$ + writer.write(" String::String(const String &other){}; \n"); //$NON-NLS-1$ + writer.write(" String::~String(){}; \n"); //$NON-NLS-1$ + writer.write(" String& String::operator=( const String &other ) \n"); //$NON-NLS-1$ + writer.write(" {return *this;} \n"); //$NON-NLS-1$ + String contents = writer.toString(); + IFile cpp= importFile("test.cpp", contents ); //$NON-NLS-1$ + + int offset1= contents.indexOf("String"); //$NON-NLS-1$ + + // conflicting renamings + RefactoringStatus status= checkConditions(cpp, offset1, "CString"); //$NON-NLS-1$ + assertRefactoringOk(status); + Change ch= getRefactorChanges(cpp, offset1, "CString"); //$NON-NLS-1$ + assertTotalChanges(countOccurrences(contents, "String"), ch); //$NON-NLS-1$ + } + + public void testBug72888() throws Exception { + StringWriter writer = new StringWriter(); + writer.write("class MyEx {}; \n"); //$NON-NLS-1$ + writer.write("void someFunc() { \n"); //$NON-NLS-1$ + writer.write(" throw MyEx(); \n"); //$NON-NLS-1$ + writer.write("}; \n"); //$NON-NLS-1$ + writer.write("int main(){ \n"); //$NON-NLS-1$ + writer.write(" try{ \n"); //$NON-NLS-1$ + writer.write(" someFunc(); \n"); //$NON-NLS-1$ + writer.write(" } catch(MyEx &e) {} \n"); //$NON-NLS-1$ + writer.write(" return 0; \n"); //$NON-NLS-1$ + writer.write("} \n"); //$NON-NLS-1$ + String contents = writer.toString(); + IFile cpp= importFile("test.cpp", contents ); //$NON-NLS-1$ + + int offset = contents.indexOf("MyEx") ; //$NON-NLS-1$ + Change changes = getRefactorChanges(cpp, offset, "xx"); //$NON-NLS-1$ + assertTotalChanges( 3, changes ); + } +} diff --git a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/refactoring/rename/RenameVariableTests.java b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/refactoring/rename/RenameVariableTests.java new file mode 100644 index 00000000000..b4d643c21a8 --- /dev/null +++ b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/refactoring/rename/RenameVariableTests.java @@ -0,0 +1,1999 @@ +/******************************************************************************* + * Copyright (c) 2005, 2007 Wind River Systems, Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Markus Schorn - initial API and implementation + *******************************************************************************/ + +package org.eclipse.cdt.ui.tests.refactoring.rename; + +import java.io.StringWriter; + +import junit.framework.Test; +import junit.framework.TestSuite; + +import org.eclipse.core.resources.IFile; +import org.eclipse.ltk.core.refactoring.Change; +import org.eclipse.ltk.core.refactoring.RefactoringStatus; + +/** + * @author markus.schorn@windriver.com + */ +public class RenameVariableTests extends RenameTests { + + public RenameVariableTests(String name) { + super(name); + } + public static Test suite(){ + return suite(true); + } + public static Test suite( boolean cleanup ) { + TestSuite suite = new TestSuite(RenameVariableTests.class); + + if (cleanup) { + suite.addTest( new RefactoringTests("cleanupProject") ); //$NON-NLS-1$ + } + return suite; + } + + public void testLocalNameConflicts() throws Exception { + createCppFwdDecls("cpp_fwd.hh"); //$NON-NLS-1$ + createCppDefs("cpp_def.hh"); //$NON-NLS-1$ + StringWriter writer = new StringWriter(); + writer.write("#include \"cpp_fwd.hh\" \n"); //$NON-NLS-1$ + writer.write("#include \"cpp_def.hh\" \n"); //$NON-NLS-1$ + writer.write("void f(int par1) { \n"); //$NON-NLS-1$ + writer.write(" int v1, x1; \n"); //$NON-NLS-1$ + writer.write(" { \n"); //$NON-NLS-1$ + writer.write(" int w1; v1++; \n"); //$NON-NLS-1$ + writer.write(" } \n"); //$NON-NLS-1$ + writer.write("} \n"); //$NON-NLS-1$ + writer.write("void class_def::method(int par2) { \n"); //$NON-NLS-1$ + writer.write(" int v2; \n"); //$NON-NLS-1$ + writer.write(" { \n"); //$NON-NLS-1$ + writer.write(" int w2; v2++; \n"); //$NON-NLS-1$ + writer.write(" } \n"); //$NON-NLS-1$ + writer.write("} \n"); //$NON-NLS-1$ + writer.write("static void class_def::static_method(int par3) { \n"); //$NON-NLS-1$ + writer.write(" int v3; \n"); //$NON-NLS-1$ + writer.write(" { \n"); //$NON-NLS-1$ + writer.write(" int w3; v3++; \n"); //$NON-NLS-1$ + writer.write(" } \n"); //$NON-NLS-1$ + writer.write("} \n"); //$NON-NLS-1$ + String contents = writer.toString(); + IFile cpp= importFile("test.cpp", contents ); //$NON-NLS-1$ + + int offset1= contents.indexOf("v1"); //$NON-NLS-1$ + int offset2= contents.indexOf("v2"); //$NON-NLS-1$ + int offset3= contents.indexOf("v3"); //$NON-NLS-1$ + + // conflicting renamings + RefactoringStatus status= checkConditions(cpp, offset1, "w1"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Shadowing \n" + + "New element: w1 \n" + + "Conflicting element type: Local variable"); //$NON-NLS-1$ + status= checkConditions(cpp, contents.indexOf("w1"), "v1"); //$NON-NLS-1$ //$NON-NLS-2$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Shadowing \n" + + "New element: v1 \n" + + "Conflicting element type: Local variable"); //$NON-NLS-1$ + status= checkConditions(cpp, contents.indexOf("x1"), "v1"); //$NON-NLS-1$ //$NON-NLS-2$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: v1 \n" + + "Conflicting element type: Local variable"); //$NON-NLS-1$ + status= checkConditions(cpp, offset1, "par1"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Shadowing \n" + + "New element: par1 \n" + + "Conflicting element type: Parameter"); //$NON-NLS-1$ + status= checkConditions(cpp, offset1, "extern_var"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Shadowing \n" + + "New element: extern_var \n" + + "Conflicting element type: Global variable"); //$NON-NLS-1$ + status= checkConditions(cpp, offset1, "var_def"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Shadowing \n" + + "New element: var_def \n" + + "Conflicting element type: Global variable"); //$NON-NLS-1$ + status= checkConditions(cpp, offset1, "enum_item"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Shadowing \n" + + "New element: enum_item \n" + + "Conflicting element type: Enumerator"); //$NON-NLS-1$ + + status= checkConditions(cpp, offset2, "w2"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Shadowing \n" + + "New element: w2 \n" + + "Conflicting element type: Local variable"); //$NON-NLS-1$ + status= checkConditions(cpp, offset2, "par2"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Shadowing \n" + + "New element: par2 \n" + + "Conflicting element type: Parameter"); //$NON-NLS-1$ + status= checkConditions(cpp, offset2, "extern_var"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Shadowing \n" + + "New element: extern_var \n" + + "Conflicting element type: Global variable"); //$NON-NLS-1$ + status= checkConditions(cpp, offset2, "var_def"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Shadowing \n" + + "New element: var_def \n" + + "Conflicting element type: Global variable"); //$NON-NLS-1$ + status= checkConditions(cpp, offset2, "enum_item"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Shadowing \n" + + "New element: enum_item \n" + + "Conflicting element type: Enumerator"); //$NON-NLS-1$ + + status= checkConditions(cpp, offset3, "w3"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Shadowing \n" + + "New element: w3 \n" + + "Conflicting element type: Local variable"); //$NON-NLS-1$ + status= checkConditions(cpp, offset3, "par3"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Shadowing \n" + + "New element: par3 \n" + + "Conflicting element type: Parameter"); //$NON-NLS-1$ + status= checkConditions(cpp, offset3, "extern_var"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Shadowing \n" + + "New element: extern_var \n" + + "Conflicting element type: Global variable"); //$NON-NLS-1$ + status= checkConditions(cpp, offset3, "var_def"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Shadowing \n" + + "New element: var_def \n" + + "Conflicting element type: Global variable"); //$NON-NLS-1$ + status= checkConditions(cpp, offset3, "enum_item"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Shadowing \n" + + "New element: enum_item \n" + + "Conflicting element type: Enumerator"); //$NON-NLS-1$ + + // renamings depending on scope + status= checkConditions(cpp, offset1, "member"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "method"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "static_member"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "static_method"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset2, "member"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Shadowing \n" + + "New element: member \n" + + "Conflicting element type: Field"); //$NON-NLS-1$ + status= checkConditions(cpp, offset2, "method"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Shadowing \n" + + "New element: method \n" + + "Conflicting element type: Method"); //$NON-NLS-1$ + status= checkConditions(cpp, offset2, "static_member"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Shadowing \n" + + "New element: static_member \n" + + "Conflicting element type: Field"); //$NON-NLS-1$ + status= checkConditions(cpp, offset2, "static_method"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Shadowing \n" + + "New element: static_method \n" + + "Conflicting element type: Method"); //$NON-NLS-1$ +// lookup inside a static method also returns non-static members +// we may want to have a check whether a binding is accessible or not. + +// status= checkConditions(cpp, offset3, "member"); //$NON-NLS-1$ +// assertRefactoringOk(status); +// status= checkConditions(cpp, offset3, "method"); //$NON-NLS-1$ +// assertRefactoringOk(status); + status= checkConditions(cpp, offset3, "static_member"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Shadowing \n" + + "New element: static_member \n" + + "Conflicting element type: Field"); //$NON-NLS-1$ + status= checkConditions(cpp, offset3, "static_method"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Shadowing \n" + + "New element: static_method \n" + + "Conflicting element type: Method"); //$NON-NLS-1$ + + // renamings that are ok. + status= checkConditions(cpp, offset1, "func_proto"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "func_proto_ov"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "func_def"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "func_def_ov"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset2, "func_proto"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset2, "func_proto_ov"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset2, "func_def"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset2, "func_def_ov"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset3, "func_proto"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset3, "func_proto_ov"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset3, "func_def"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset3, "func_def_ov"); //$NON-NLS-1$ + assertRefactoringOk(status); + + // renamings that are ok. + status= checkConditions(cpp, offset1, "class_fwd"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "struct_fwd"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "union_fwd"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "class_def"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Shadowing \n" + + "New element: class_def \n" + + "Conflicting element type: Constructor"); //$NON-NLS-1$ + status= checkConditions(cpp, offset1, "struct_def"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "union_def"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "enum_def"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "typedef_def"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "namespace_def"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "st_member"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "un_member"); //$NON-NLS-1$ + assertRefactoringOk(status); + + status= checkConditions(cpp, offset2, "class_fwd"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset2, "struct_fwd"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset2, "union_fwd"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset2, "class_def"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Shadowing \n" + + "New element: class_def \n" + + "Conflicting element type: Constructor"); //$NON-NLS-1$ + status= checkConditions(cpp, offset2, "struct_def"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset2, "union_def"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset2, "enum_def"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset2, "typedef_def"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset2, "namespace_def"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset2, "st_member"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset2, "un_member"); //$NON-NLS-1$ + assertRefactoringOk(status); + + status= checkConditions(cpp, offset3, "class_fwd"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset3, "struct_fwd"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset3, "union_fwd"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset3, "class_def"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Shadowing \n" + + "New element: class_def \n" + + "Conflicting element type: Constructor"); //$NON-NLS-1$ + status= checkConditions(cpp, offset3, "struct_def"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset3, "union_def"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset3, "enum_def"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset3, "typedef_def"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset3, "namespace_def"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset3, "st_member"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset3, "un_member"); //$NON-NLS-1$ + assertRefactoringOk(status); + } + + public void testLocalNameConflictsPlainC() throws Exception { + createCFwdDecls("c_fwd.h"); //$NON-NLS-1$ + createCDefs("c_def.h"); //$NON-NLS-1$ + StringWriter writer = new StringWriter(); + writer.write("#include \"c_fwd.h\" \n"); //$NON-NLS-1$ + writer.write("#include \"c_def.h\" \n"); //$NON-NLS-1$ + writer.write("void f(int par1) { \n"); //$NON-NLS-1$ + writer.write(" int v1, x1, w1; \n"); //$NON-NLS-1$ + writer.write(" w1++; v1++; \n"); //$NON-NLS-1$ + writer.write("} \n"); //$NON-NLS-1$ + String contents = writer.toString(); + IFile cpp= importFile("test.c", contents ); //$NON-NLS-1$ + + int offset1= contents.indexOf("v1"); //$NON-NLS-1$ + + // conflicting renamings + RefactoringStatus status= checkConditions(cpp, offset1, "w1"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: w1 \n" + + "Conflicting element type: Local variable"); //$NON-NLS-1$ + status= checkConditions(cpp, contents.indexOf("w1"), "v1"); //$NON-NLS-1$ //$NON-NLS-2$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: v1 \n" + + "Conflicting element type: Local variable"); //$NON-NLS-1$ + status= checkConditions(cpp, contents.indexOf("x1"), "v1"); //$NON-NLS-1$ //$NON-NLS-2$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: v1 \n" + + "Conflicting element type: Local variable"); //$NON-NLS-1$ + status= checkConditions(cpp, offset1, "par1"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Shadowing \n" + + "New element: par1 \n" + + "Conflicting element type: Parameter"); //$NON-NLS-1$ + status= checkConditions(cpp, offset1, "extern_var"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Shadowing \n" + + "New element: extern_var \n" + + "Conflicting element type: Global variable"); //$NON-NLS-1$ + status= checkConditions(cpp, offset1, "var_def"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Shadowing \n" + + "New element: var_def \n" + + "Conflicting element type: Global variable"); //$NON-NLS-1$ + status= checkConditions(cpp, offset1, "enum_item"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Shadowing \n" + + "New element: enum_item \n" + + "Conflicting element type: Enumerator"); //$NON-NLS-1$ + + // renamings that are ok. + status= checkConditions(cpp, offset1, "func_proto"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "func_def"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "struct_fwd"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "union_fwd"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "struct_def"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "union_def"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "enum_def"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "typedef_def"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "st_member"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "un_member"); //$NON-NLS-1$ + assertRefactoringOk(status); + + } + + + public void testParameterNameConflicts() throws Exception { + createCppFwdDecls("cpp_fwd.hh"); //$NON-NLS-1$ + createCppDefs("cpp_def.hh"); //$NON-NLS-1$ + StringWriter writer = new StringWriter(); + writer.write("#include \"cpp_fwd.hh\" \n"); //$NON-NLS-1$ + writer.write("#include \"cpp_def.hh\" \n"); //$NON-NLS-1$ + writer.write("void f(int par1, int v1) {\n"); //$NON-NLS-1$ + writer.write(" { \n"); //$NON-NLS-1$ + writer.write(" int w1; v1++; \n"); //$NON-NLS-1$ + writer.write(" } \n"); //$NON-NLS-1$ + writer.write("} \n"); //$NON-NLS-1$ + writer.write("void class_def::method(int par2, int v2) { \n"); //$NON-NLS-1$ + writer.write(" { \n"); //$NON-NLS-1$ + writer.write(" int w2; v2++; \n"); //$NON-NLS-1$ + writer.write(" } \n"); //$NON-NLS-1$ + writer.write("} \n"); //$NON-NLS-1$ + writer.write("static void class_def::static_method(int par3, int v3) { \n"); //$NON-NLS-1$ + writer.write(" { \n"); //$NON-NLS-1$ + writer.write(" int w3; v3++; \n"); //$NON-NLS-1$ + writer.write(" } \n"); //$NON-NLS-1$ + writer.write("} \n"); //$NON-NLS-1$ + String contents = writer.toString(); + IFile cpp= importFile("test.cpp", contents ); //$NON-NLS-1$ + + int offset1= contents.indexOf("v1"); //$NON-NLS-1$ + int offset2= contents.indexOf("v2"); //$NON-NLS-1$ + int offset3= contents.indexOf("v3"); //$NON-NLS-1$ + + // conflicting renamings + RefactoringStatus status= checkConditions(cpp, offset1, "w1"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Shadowing \n" + + "New element: w1 \n" + + "Conflicting element type: Local variable"); //$NON-NLS-1$ + status= checkConditions(cpp, contents.indexOf("w1"), "v1"); //$NON-NLS-1$ //$NON-NLS-2$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Shadowing \n" + + "New element: v1 \n" + + "Conflicting element type: Parameter"); //$NON-NLS-1$ + status= checkConditions(cpp, contents.indexOf("par1"), "v1"); //$NON-NLS-1$ //$NON-NLS-2$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: v1 \n" + + "Conflicting element type: Parameter"); //$NON-NLS-1$ + status= checkConditions(cpp, offset1, "par1"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: par1 \n" + + "Conflicting element type: Parameter"); //$NON-NLS-1$ + status= checkConditions(cpp, offset1, "extern_var"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Shadowing \n" + + "New element: extern_var \n" + + "Conflicting element type: Global variable"); //$NON-NLS-1$ + status= checkConditions(cpp, offset1, "var_def"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Shadowing \n" + + "New element: var_def \n" + + "Conflicting element type: Global variable"); //$NON-NLS-1$ + status= checkConditions(cpp, offset1, "enum_item"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Shadowing \n" + + "New element: enum_item \n" + + "Conflicting element type: Enumerator"); //$NON-NLS-1$ + + status= checkConditions(cpp, offset2, "w2"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Shadowing \n" + + "New element: w2 \n" + + "Conflicting element type: Local variable"); //$NON-NLS-1$ + status= checkConditions(cpp, offset2, "par2"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: par2 \n" + + "Conflicting element type: Parameter"); //$NON-NLS-1$ + status= checkConditions(cpp, offset2, "extern_var"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Shadowing \n" + + "New element: extern_var \n" + + "Conflicting element type: Global variable"); //$NON-NLS-1$ + status= checkConditions(cpp, offset2, "var_def"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Shadowing \n" + + "New element: var_def \n" + + "Conflicting element type: Global variable"); //$NON-NLS-1$ + status= checkConditions(cpp, offset2, "enum_item"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Shadowing \n" + + "New element: enum_item \n" + + "Conflicting element type: Enumerator"); //$NON-NLS-1$ + + status= checkConditions(cpp, offset3, "w3"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Shadowing \n" + + "New element: w3 \n" + + "Conflicting element type: Local variable"); //$NON-NLS-1$ + status= checkConditions(cpp, offset3, "par3"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: par3 \n" + + "Conflicting element type: Parameter"); //$NON-NLS-1$ + status= checkConditions(cpp, offset3, "extern_var"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Shadowing \n" + + "New element: extern_var \n" + + "Conflicting element type: Global variable"); //$NON-NLS-1$ + status= checkConditions(cpp, offset3, "var_def"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Shadowing \n" + + "New element: var_def \n" + + "Conflicting element type: Global variable"); //$NON-NLS-1$ + status= checkConditions(cpp, offset3, "enum_item"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Shadowing \n" + + "New element: enum_item \n" + + "Conflicting element type: Enumerator"); //$NON-NLS-1$ + + // renamings depending on scope + status= checkConditions(cpp, offset1, "member"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "method"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "static_member"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "static_method"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset2, "member"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Shadowing \n" + + "New element: member \n" + + "Conflicting element type: Field"); //$NON-NLS-1$ + status= checkConditions(cpp, offset2, "method"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Shadowing \n" + + "New element: method \n" + + "Conflicting element type: Method"); //$NON-NLS-1$ + status= checkConditions(cpp, offset2, "static_member"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Shadowing \n" + + "New element: static_member \n" + + "Conflicting element type: Field"); //$NON-NLS-1$ + status= checkConditions(cpp, offset2, "static_method"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Shadowing \n" + + "New element: static_method \n" + + "Conflicting element type: Method"); //$NON-NLS-1$ +// lookup inside a static method also returns non-static members +// we may want to have a check whether a binding is accessible or not. + +// status= checkConditions(cpp, offset3, "member"); //$NON-NLS-1$ +// assertRefactoringOk(status); +// status= checkConditions(cpp, offset3, "method"); //$NON-NLS-1$ +// assertRefactoringOk(status); + status= checkConditions(cpp, offset3, "static_member"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Shadowing \n" + + "New element: static_member \n" + + "Conflicting element type: Field"); //$NON-NLS-1$ + status= checkConditions(cpp, offset3, "static_method"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Shadowing \n" + + "New element: static_method \n" + + "Conflicting element type: Method"); //$NON-NLS-1$ + + // renamings that are ok. + status= checkConditions(cpp, offset1, "func_proto"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "func_proto_ov"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "func_def"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "func_def_ov"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset2, "func_proto"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset2, "func_proto_ov"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset2, "func_def"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset2, "func_def_ov"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset3, "func_proto"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset3, "func_proto_ov"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset3, "func_def"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset3, "func_def_ov"); //$NON-NLS-1$ + assertRefactoringOk(status); + + // renamings that are ok. + status= checkConditions(cpp, offset1, "class_fwd"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "struct_fwd"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "union_fwd"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "class_def"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Shadowing \n" + + "New element: class_def \n" + + "Conflicting element type: Constructor"); //$NON-NLS-1$ + status= checkConditions(cpp, offset1, "struct_def"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "union_def"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "enum_def"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "typedef_def"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "namespace_def"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "st_member"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "un_member"); //$NON-NLS-1$ + assertRefactoringOk(status); + + status= checkConditions(cpp, offset2, "class_fwd"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset2, "struct_fwd"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset2, "union_fwd"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset2, "class_def"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Shadowing \n" + + "New element: class_def \n" + + "Conflicting element type: Constructor"); //$NON-NLS-1$ + status= checkConditions(cpp, offset2, "struct_def"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset2, "union_def"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset2, "enum_def"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset2, "typedef_def"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset2, "namespace_def"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset2, "st_member"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset2, "un_member"); //$NON-NLS-1$ + assertRefactoringOk(status); + + status= checkConditions(cpp, offset3, "class_fwd"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset3, "struct_fwd"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset3, "union_fwd"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset3, "class_def"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Shadowing \n" + + "New element: class_def \n" + + "Conflicting element type: Constructor"); //$NON-NLS-1$ + status= checkConditions(cpp, offset3, "struct_def"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset3, "union_def"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset3, "enum_def"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset3, "typedef_def"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset3, "namespace_def"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset3, "st_member"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset3, "un_member"); //$NON-NLS-1$ + assertRefactoringOk(status); + } + + public void testParameterNameConflictsPlainC() throws Exception { + createCFwdDecls("c_fwd.h"); //$NON-NLS-1$ + createCDefs("c_def.h"); //$NON-NLS-1$ + StringWriter writer = new StringWriter(); + writer.write("#include \"c_fwd.h\" \n"); //$NON-NLS-1$ + writer.write("#include \"c_def.h\" \n"); //$NON-NLS-1$ + writer.write("void f(int par1, int v1) {\n"); //$NON-NLS-1$ + writer.write(" int w1; v1++; \n"); //$NON-NLS-1$ + writer.write("} \n"); //$NON-NLS-1$ + String contents = writer.toString(); + IFile c= importFile("test.c", contents ); //$NON-NLS-1$ + + int offset1= contents.indexOf("v1"); //$NON-NLS-1$ + + // conflicting renamings + RefactoringStatus status= checkConditions(c, offset1, "w1"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Shadowing \n" + + "New element: w1 \n" + + "Conflicting element type: Local variable"); //$NON-NLS-1$ + status= checkConditions(c, contents.indexOf("w1"), "v1"); //$NON-NLS-1$ //$NON-NLS-2$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Shadowing \n" + + "New element: v1 \n" + + "Conflicting element type: Parameter"); //$NON-NLS-1$ + status= checkConditions(c, contents.indexOf("par1"), "v1"); //$NON-NLS-1$ //$NON-NLS-2$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: v1 \n" + + "Conflicting element type: Parameter"); //$NON-NLS-1$ + status= checkConditions(c, offset1, "par1"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: par1 \n" + + "Conflicting element type: Parameter"); //$NON-NLS-1$ + status= checkConditions(c, offset1, "extern_var"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Shadowing \n" + + "New element: extern_var \n" + + "Conflicting element type: Global variable"); //$NON-NLS-1$ + status= checkConditions(c, offset1, "var_def"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Shadowing \n" + + "New element: var_def \n" + + "Conflicting element type: Global variable"); //$NON-NLS-1$ + status= checkConditions(c, offset1, "enum_item"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Shadowing \n" + + "New element: enum_item \n" + + "Conflicting element type: Enumerator"); //$NON-NLS-1$ + + // renamings that are ok. + status= checkConditions(c, offset1, "func_proto"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(c, offset1, "func_proto_ov"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(c, offset1, "func_def"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(c, offset1, "func_def_ov"); //$NON-NLS-1$ + assertRefactoringOk(status); + + // renamings that are ok. + status= checkConditions(c, offset1, "struct_fwd"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(c, offset1, "union_fwd"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(c, offset1, "struct_def"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(c, offset1, "union_def"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(c, offset1, "enum_def"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(c, offset1, "typedef_def"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(c, offset1, "st_member"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(c, offset1, "un_member"); //$NON-NLS-1$ + assertRefactoringOk(status); + } + + public void testVaribleNameConflicts() throws Exception { + createCppFwdDecls("cpp_fwd.hh"); //$NON-NLS-1$ + createCppDefs("cpp_def.hh"); //$NON-NLS-1$ + StringWriter writer = new StringWriter(); + writer.write("#include \"cpp_fwd.hh\" \n"); //$NON-NLS-1$ + writer.write("#include \"cpp_def.hh\" \n"); //$NON-NLS-1$ + writer.write("int v1, v2, v3; \n"); //$NON-NLS-1$ + writer.write("static int s1; \n"); //$NON-NLS-1$ + writer.write("static int s2; \n"); //$NON-NLS-1$ + writer.write("void f(int par1){ \n"); //$NON-NLS-1$ + writer.write(" { \n"); //$NON-NLS-1$ + writer.write(" int w1; v1++; \n"); //$NON-NLS-1$ + writer.write(" } \n"); //$NON-NLS-1$ + writer.write("} \n"); //$NON-NLS-1$ + writer.write("void class_def::method(int par2) { \n"); //$NON-NLS-1$ + writer.write(" { \n"); //$NON-NLS-1$ + writer.write(" int w2; v2++; \n"); //$NON-NLS-1$ + writer.write(" } \n"); //$NON-NLS-1$ + writer.write("} \n"); //$NON-NLS-1$ + writer.write("static void class_def::static_method(int par3) { \n"); //$NON-NLS-1$ + writer.write(" { \n"); //$NON-NLS-1$ + writer.write(" int w3; v3++; \n"); //$NON-NLS-1$ + writer.write(" } \n"); //$NON-NLS-1$ + writer.write("} \n"); //$NON-NLS-1$ + String contents = writer.toString(); + IFile cpp= importFile("test.cpp", contents ); //$NON-NLS-1$ + + writer = new StringWriter(); + writer.write( "static int static_other_file; \n" ); //$NON-NLS-1$ + importFile( "other.cpp", writer.toString() ); //$NON-NLS-1$ + + + int offset1= contents.indexOf("v1"); //$NON-NLS-1$ + int offset2= contents.indexOf("v2"); //$NON-NLS-1$ + int offset3= contents.indexOf("v3"); //$NON-NLS-1$ + + // conflicting renamings + RefactoringStatus status= checkConditions(cpp, offset1, "w1"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Shadowing \n" + + "New element: w1 \n" + + "Conflicting element type: Local variable"); //$NON-NLS-1$ + status= checkConditions(cpp, contents.indexOf("w1"), "v1"); //$NON-NLS-1$ //$NON-NLS-2$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Shadowing \n" + + "New element: v1 \n" + + "Conflicting element type: Global variable"); //$NON-NLS-1$ + status= checkConditions(cpp, contents.indexOf("par1"), "v1"); //$NON-NLS-1$ //$NON-NLS-2$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Shadowing \n" + + "New element: v1 \n" + + "Conflicting element type: Global variable"); //$NON-NLS-1$ + status= checkConditions(cpp, offset1, "par1"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Shadowing \n" + + "New element: par1 \n" + + "Conflicting element type: Parameter"); //$NON-NLS-1$ + status= checkConditions(cpp, offset1, "extern_var"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: extern_var \n" + + "Conflicting element type: Global variable"); //$NON-NLS-1$ + status= checkConditions(cpp, offset1, "var_def"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: var_def \n" + + "Conflicting element type: Global variable"); //$NON-NLS-1$ + status= checkConditions(cpp, offset1, "enum_item"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: enum_item \n" + + "Conflicting element type: Enumerator"); //$NON-NLS-1$ + + status= checkConditions(cpp, offset2, "w2"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Shadowing \n" + + "New element: w2 \n" + + "Conflicting element type: Local variable"); //$NON-NLS-1$ + status= checkConditions(cpp, offset2, "par2"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Shadowing \n" + + "New element: par2 \n" + + "Conflicting element type: Parameter"); //$NON-NLS-1$ + status= checkConditions(cpp, offset2, "extern_var"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: extern_var \n" + + "Conflicting element type: Global variable"); //$NON-NLS-1$ + status= checkConditions(cpp, offset2, "var_def"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: var_def \n" + + "Conflicting element type: Global variable"); //$NON-NLS-1$ + status= checkConditions(cpp, offset2, "enum_item"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: enum_item \n" + + "Conflicting element type: Enumerator"); //$NON-NLS-1$ + + status= checkConditions(cpp, offset3, "w3"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Shadowing \n" + + "New element: w3 \n" + + "Conflicting element type: Local variable"); //$NON-NLS-1$ + status= checkConditions(cpp, offset3, "par3"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Shadowing \n" + + "New element: par3 \n" + + "Conflicting element type: Parameter"); //$NON-NLS-1$ + status= checkConditions(cpp, offset3, "extern_var"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: extern_var \n" + + "Conflicting element type: Global variable"); //$NON-NLS-1$ + status= checkConditions(cpp, offset3, "var_def"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: var_def \n" + + "Conflicting element type: Global variable"); //$NON-NLS-1$ + status= checkConditions(cpp, offset3, "enum_item"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: enum_item \n" + + "Conflicting element type: Enumerator"); //$NON-NLS-1$ + + // renamings depending on scope + status= checkConditions(cpp, offset1, "member"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "method"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "static_member"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "static_method"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset2, "member"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Shadowing \n" + + "New element: member \n" + + "Conflicting element type: Field"); //$NON-NLS-1$ + status= checkConditions(cpp, offset2, "method"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Shadowing \n" + + "New element: method \n" + + "Conflicting element type: Method"); //$NON-NLS-1$ + status= checkConditions(cpp, offset2, "static_member"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Shadowing \n" + + "New element: static_member \n" + + "Conflicting element type: Field"); //$NON-NLS-1$ + status= checkConditions(cpp, offset2, "static_method"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Shadowing \n" + + "New element: static_method \n" + + "Conflicting element type: Method"); //$NON-NLS-1$ +// lookup inside a static method also returns non-static members +// we may want to have a check whether a binding is accessible or not. + +// status= checkConditions(cpp, offset3, "member"); //$NON-NLS-1$ +// assertRefactoringOk(status); +// status= checkConditions(cpp, offset3, "method"); //$NON-NLS-1$ +// assertRefactoringOk(status); + status= checkConditions(cpp, offset3, "static_member"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Shadowing \n" + + "New element: static_member \n" + + "Conflicting element type: Field"); //$NON-NLS-1$ + status= checkConditions(cpp, offset3, "static_method"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Shadowing \n" + + "New element: static_method \n" + + "Conflicting element type: Method"); //$NON-NLS-1$ + + // renamings conflicting with global stuff. + status= checkConditions(cpp, offset1, "func_proto"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: func_proto \n" + + "Conflicting element type: Global function"); //$NON-NLS-1$ + status= checkConditions(cpp, offset1, "func_proto_ov"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: func_proto_ov \n" + + "Conflicting element type: Global function"); //$NON-NLS-1$ + status= checkConditions(cpp, offset1, "func_def"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: func_def \n" + + "Conflicting element type: Global function"); //$NON-NLS-1$ + // would be good to see an error here + status= checkConditions(cpp, offset1, "func_def_ov"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: func_def_ov \n" + + "Conflicting element type: Global function"); //$NON-NLS-1$ + status= checkConditions(cpp, offset2, "func_proto"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: func_proto \n" + + "Conflicting element type: Global function"); //$NON-NLS-1$ + status= checkConditions(cpp, offset2, "func_proto_ov"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: func_proto_ov \n" + + "Conflicting element type: Global function"); //$NON-NLS-1$ + status= checkConditions(cpp, offset2, "func_def"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: func_def \n" + + "Conflicting element type: Global function"); //$NON-NLS-1$ + // would be good to see an error here + status= checkConditions(cpp, offset2, "func_def_ov"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: func_def_ov \n" + + "Conflicting element type: Global function"); //$NON-NLS-1$ + status= checkConditions(cpp, offset3, "func_proto"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: func_proto \n" + + "Conflicting element type: Global function"); //$NON-NLS-1$ + status= checkConditions(cpp, offset3, "func_proto_ov"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: func_proto_ov \n" + + "Conflicting element type: Global function"); //$NON-NLS-1$ + status= checkConditions(cpp, offset3, "func_def"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: func_def \n" + + "Conflicting element type: Global function"); //$NON-NLS-1$ + status= checkConditions(cpp, offset3, "func_def_ov"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: func_def_ov \n" + + "Conflicting element type: Global function"); //$NON-NLS-1$ + + // renamings that are ok. + status= checkConditions(cpp, offset1, "class_fwd"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "struct_fwd"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "union_fwd"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "class_def"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Shadowing \n" + + "New element: class_def \n" + + "Conflicting element type: Constructor"); //$NON-NLS-1$ + status= checkConditions(cpp, offset1, "struct_def"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "union_def"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "enum_def"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "typedef_def"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "namespace_def"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "st_member"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "un_member"); //$NON-NLS-1$ + assertRefactoringOk(status); + + status= checkConditions(cpp, offset2, "class_fwd"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset2, "struct_fwd"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset2, "union_fwd"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset2, "class_def"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Shadowing \n" + + "New element: class_def \n" + + "Conflicting element type: Constructor"); //$NON-NLS-1$ + status= checkConditions(cpp, offset2, "struct_def"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset2, "union_def"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset2, "enum_def"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset2, "typedef_def"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset2, "namespace_def"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset2, "st_member"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset2, "un_member"); //$NON-NLS-1$ + assertRefactoringOk(status); + + status= checkConditions(cpp, offset3, "class_fwd"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset3, "struct_fwd"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset3, "union_fwd"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset3, "class_def"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Shadowing \n" + + "New element: class_def \n" + + "Conflicting element type: Constructor"); //$NON-NLS-1$ + status= checkConditions(cpp, offset3, "struct_def"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset3, "union_def"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset3, "enum_def"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset3, "typedef_def"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset3, "namespace_def"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset3, "st_member"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset3, "un_member"); //$NON-NLS-1$ + assertRefactoringOk(status); + + // file static stuff + status= checkConditions(cpp, contents.indexOf("s1"), "s2"); //$NON-NLS-1$ //$NON-NLS-2$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: s2 \n" + + "Conflicting element type: File static variable"); //$NON-NLS-1$ + + status= checkConditions(cpp, contents.indexOf("s1"), "static_other_file"); //$NON-NLS-1$ //$NON-NLS-2$ + assertRefactoringOk(status); + } + + public void testVaribleNameConflictsPlainC() throws Exception { + createCFwdDecls("c_fwd.h"); //$NON-NLS-1$ + createCDefs("c_def.h"); //$NON-NLS-1$ + StringWriter writer = new StringWriter(); + writer.write("#include \"c_fwd.h\" \n"); //$NON-NLS-1$ + writer.write("#include \"c_def.h\" \n"); //$NON-NLS-1$ + writer.write("int v1; \n"); //$NON-NLS-1$ + writer.write("static int s1; \n"); //$NON-NLS-1$ + writer.write("static int s2; \n"); //$NON-NLS-1$ + writer.write("void f(int par1){ \n"); //$NON-NLS-1$ + writer.write(" int w1; v1++; \n"); //$NON-NLS-1$ + writer.write("} \n"); //$NON-NLS-1$ + String contents = writer.toString(); + IFile c= importFile("test.c", contents ); //$NON-NLS-1$ + + writer = new StringWriter(); + writer.write( "static int static_other_file; \n" ); //$NON-NLS-1$ + importFile( "other.c", writer.toString() ); //$NON-NLS-1$ + + + int offset1= contents.indexOf("v1"); //$NON-NLS-1$ + + // conflicting renamings + RefactoringStatus status= checkConditions(c, offset1, "w1"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Shadowing \n" + + "New element: w1 \n" + + "Conflicting element type: Local variable"); //$NON-NLS-1$ + status= checkConditions(c, contents.indexOf("w1"), "v1"); //$NON-NLS-1$ //$NON-NLS-2$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Shadowing \n" + + "New element: v1 \n" + + "Conflicting element type: Global variable"); //$NON-NLS-1$ + status= checkConditions(c, contents.indexOf("par1"), "v1"); //$NON-NLS-1$ //$NON-NLS-2$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Shadowing \n" + + "New element: v1 \n" + + "Conflicting element type: Global variable"); //$NON-NLS-1$ + status= checkConditions(c, offset1, "par1"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Shadowing \n" + + "New element: par1 \n" + + "Conflicting element type: Parameter"); //$NON-NLS-1$ + status= checkConditions(c, offset1, "extern_var"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: extern_var \n" + + "Conflicting element type: Global variable"); //$NON-NLS-1$ + status= checkConditions(c, offset1, "var_def"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: var_def \n" + + "Conflicting element type: Global variable"); //$NON-NLS-1$ + status= checkConditions(c, offset1, "enum_item"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: enum_item \n" + + "Conflicting element type: Enumerator"); //$NON-NLS-1$ + + // renamings conflicting with global stuff. + status= checkConditions(c, offset1, "func_proto"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: func_proto \n" + + "Conflicting element type: Global function"); //$NON-NLS-1$ + status= checkConditions(c, offset1, "func_def"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: func_def \n" + + "Conflicting element type: Global function"); //$NON-NLS-1$ + + // renamings that are ok. + status= checkConditions(c, offset1, "struct_fwd"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(c, offset1, "union_fwd"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(c, offset1, "struct_def"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(c, offset1, "union_def"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(c, offset1, "enum_def"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(c, offset1, "typedef_def"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(c, offset1, "st_member"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(c, offset1, "un_member"); //$NON-NLS-1$ + assertRefactoringOk(status); + + // file static stuff + status= checkConditions(c, contents.indexOf("s1"), "s2"); //$NON-NLS-1$ //$NON-NLS-2$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: s2 \n" + + "Conflicting element type: File static variable"); //$NON-NLS-1$ + + status= checkConditions(c, contents.indexOf("s1"), "static_other_file"); //$NON-NLS-1$ //$NON-NLS-2$ + assertRefactoringOk(status); + } + + public void testEnumeratorNameConflicts() throws Exception { + createCppFwdDecls("cpp_fwd.hh"); //$NON-NLS-1$ + createCppDefs("cpp_def.hh"); //$NON-NLS-1$ + StringWriter writer = new StringWriter(); + writer.write("#include \"cpp_fwd.hh\" \n"); //$NON-NLS-1$ + writer.write("#include \"cpp_def.hh\" \n"); //$NON-NLS-1$ + writer.write("enum E {v1, v2, v3}; \n"); //$NON-NLS-1$ + writer.write("static int s1; \n"); //$NON-NLS-1$ + writer.write("static int s2; \n"); //$NON-NLS-1$ + writer.write("void f(int par1){ \n"); //$NON-NLS-1$ + writer.write(" { \n"); //$NON-NLS-1$ + writer.write(" int w1=v1; \n"); //$NON-NLS-1$ + writer.write(" } \n"); //$NON-NLS-1$ + writer.write("} \n"); //$NON-NLS-1$ + writer.write("void class_def::method(int par2) { \n"); //$NON-NLS-1$ + writer.write(" { \n"); //$NON-NLS-1$ + writer.write(" int w2=v2; \n"); //$NON-NLS-1$ + writer.write(" } \n"); //$NON-NLS-1$ + writer.write("} \n"); //$NON-NLS-1$ + writer.write("static void class_def::static_method(int par3) { \n"); //$NON-NLS-1$ + writer.write(" { \n"); //$NON-NLS-1$ + writer.write(" int w3=v3; \n"); //$NON-NLS-1$ + writer.write(" } \n"); //$NON-NLS-1$ + writer.write("} \n"); //$NON-NLS-1$ + String contents = writer.toString(); + IFile cpp= importFile("test.cpp", contents ); //$NON-NLS-1$ + + writer = new StringWriter(); + writer.write( "static int static_other_file; \n" ); //$NON-NLS-1$ + importFile( "other.cpp", writer.toString() ); //$NON-NLS-1$ + + + int offset1= contents.indexOf("v1"); //$NON-NLS-1$ + int offset2= contents.indexOf("v2"); //$NON-NLS-1$ + int offset3= contents.indexOf("v3"); //$NON-NLS-1$ + + // conflicting renamings + RefactoringStatus status= checkConditions(cpp, offset1, "w1"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Shadowing \n" + + "New element: w1 \n" + + "Conflicting element type: Local variable"); //$NON-NLS-1$ + status= checkConditions(cpp, contents.indexOf("w1"), "v1"); //$NON-NLS-1$ //$NON-NLS-2$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Shadowing \n" + + "New element: v1 \n" + + "Conflicting element type: Enumerator"); //$NON-NLS-1$ + status= checkConditions(cpp, contents.indexOf("par1"), "v1"); //$NON-NLS-1$ //$NON-NLS-2$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Shadowing \n" + + "New element: v1 \n" + + "Conflicting element type: Enumerator"); //$NON-NLS-1$ + status= checkConditions(cpp, offset1, "par1"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Shadowing \n" + + "New element: par1 \n" + + "Conflicting element type: Parameter"); //$NON-NLS-1$ + status= checkConditions(cpp, offset1, "extern_var"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: extern_var \n" + + "Conflicting element type: Global variable"); //$NON-NLS-1$ + status= checkConditions(cpp, offset1, "var_def"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: var_def \n" + + "Conflicting element type: Global variable"); //$NON-NLS-1$ + status= checkConditions(cpp, offset1, "enum_item"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: enum_item \n" + + "Conflicting element type: Enumerator"); //$NON-NLS-1$ + + status= checkConditions(cpp, offset2, "w2"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Shadowing \n" + + "New element: w2 \n" + + "Conflicting element type: Local variable"); //$NON-NLS-1$ + status= checkConditions(cpp, offset2, "par2"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Shadowing \n" + + "New element: par2 \n" + + "Conflicting element type: Parameter"); //$NON-NLS-1$ + status= checkConditions(cpp, offset2, "extern_var"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: extern_var \n" + + "Conflicting element type: Global variable"); //$NON-NLS-1$ + status= checkConditions(cpp, offset2, "var_def"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: var_def \n" + + "Conflicting element type: Global variable"); //$NON-NLS-1$ + status= checkConditions(cpp, offset2, "enum_item"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: enum_item \n" + + "Conflicting element type: Enumerator"); //$NON-NLS-1$ + + status= checkConditions(cpp, offset3, "w3"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Shadowing \n" + + "New element: w3 \n" + + "Conflicting element type: Local variable"); //$NON-NLS-1$ + status= checkConditions(cpp, offset3, "par3"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Shadowing \n" + + "New element: par3 \n" + + "Conflicting element type: Parameter"); //$NON-NLS-1$ + status= checkConditions(cpp, offset3, "extern_var"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: extern_var \n" + + "Conflicting element type: Global variable"); //$NON-NLS-1$ + status= checkConditions(cpp, offset3, "var_def"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: var_def \n" + + "Conflicting element type: Global variable"); //$NON-NLS-1$ + status= checkConditions(cpp, offset3, "enum_item"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: enum_item \n" + + "Conflicting element type: Enumerator"); //$NON-NLS-1$ + + // renamings depending on scope + status= checkConditions(cpp, offset1, "member"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "method"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "static_member"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "static_method"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset2, "member"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Shadowing \n" + + "New element: member \n" + + "Conflicting element type: Field"); //$NON-NLS-1$ + status= checkConditions(cpp, offset2, "method"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Shadowing \n" + + "New element: method \n" + + "Conflicting element type: Method"); //$NON-NLS-1$ + status= checkConditions(cpp, offset2, "static_member"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Shadowing \n" + + "New element: static_member \n" + + "Conflicting element type: Field"); //$NON-NLS-1$ + status= checkConditions(cpp, offset2, "static_method"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Shadowing \n" + + "New element: static_method \n" + + "Conflicting element type: Method"); //$NON-NLS-1$ + status= checkConditions(cpp, offset3, "static_member"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Shadowing \n" + + "New element: static_member \n" + + "Conflicting element type: Field"); //$NON-NLS-1$ + status= checkConditions(cpp, offset3, "static_method"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Shadowing \n" + + "New element: static_method \n" + + "Conflicting element type: Method"); //$NON-NLS-1$ + + // renamings conflicting with global stuff. + status= checkConditions(cpp, offset1, "func_proto"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: func_proto \n" + + "Conflicting element type: Global function"); //$NON-NLS-1$ + status= checkConditions(cpp, offset1, "func_proto_ov"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: func_proto_ov \n" + + "Conflicting element type: Global function"); //$NON-NLS-1$ + status= checkConditions(cpp, offset1, "func_def"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: func_def \n" + + "Conflicting element type: Global function"); //$NON-NLS-1$ + // would be good to see an error here + status= checkConditions(cpp, offset1, "func_def_ov"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: func_def_ov \n" + + "Conflicting element type: Global function"); //$NON-NLS-1$ + status= checkConditions(cpp, offset2, "func_proto"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: func_proto \n" + + "Conflicting element type: Global function"); //$NON-NLS-1$ + status= checkConditions(cpp, offset2, "func_proto_ov"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: func_proto_ov \n" + + "Conflicting element type: Global function"); //$NON-NLS-1$ + status= checkConditions(cpp, offset2, "func_def"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: func_def \n" + + "Conflicting element type: Global function"); //$NON-NLS-1$ + // would be good to see an error here + status= checkConditions(cpp, offset2, "func_def_ov"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: func_def_ov \n" + + "Conflicting element type: Global function"); //$NON-NLS-1$ + status= checkConditions(cpp, offset3, "func_proto"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: func_proto \n" + + "Conflicting element type: Global function"); //$NON-NLS-1$ + status= checkConditions(cpp, offset3, "func_proto_ov"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: func_proto_ov \n" + + "Conflicting element type: Global function"); //$NON-NLS-1$ + status= checkConditions(cpp, offset3, "func_def"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: func_def \n" + + "Conflicting element type: Global function"); //$NON-NLS-1$ + status= checkConditions(cpp, offset3, "func_def_ov"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: func_def_ov \n" + + "Conflicting element type: Global function"); //$NON-NLS-1$ + + // renamings that are ok. + status= checkConditions(cpp, offset1, "class_fwd"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "struct_fwd"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "union_fwd"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "class_def"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Shadowing \n" + + "New element: class_def \n" + + "Conflicting element type: Constructor"); //$NON-NLS-1$ + status= checkConditions(cpp, offset1, "struct_def"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "union_def"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "enum_def"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "typedef_def"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "namespace_def"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "st_member"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "un_member"); //$NON-NLS-1$ + assertRefactoringOk(status); + + status= checkConditions(cpp, offset2, "class_fwd"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset2, "struct_fwd"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset2, "union_fwd"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset2, "class_def"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Shadowing \n" + + "New element: class_def \n" + + "Conflicting element type: Constructor"); //$NON-NLS-1$ + status= checkConditions(cpp, offset2, "struct_def"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset2, "union_def"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset2, "enum_def"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset2, "typedef_def"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset2, "namespace_def"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset2, "st_member"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset2, "un_member"); //$NON-NLS-1$ + assertRefactoringOk(status); + + status= checkConditions(cpp, offset3, "class_fwd"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset3, "struct_fwd"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset3, "union_fwd"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset3, "class_def"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Shadowing \n" + + "New element: class_def \n" + + "Conflicting element type: Constructor"); //$NON-NLS-1$ + status= checkConditions(cpp, offset3, "struct_def"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset3, "union_def"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset3, "enum_def"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset3, "typedef_def"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset3, "namespace_def"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset3, "st_member"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset3, "un_member"); //$NON-NLS-1$ + assertRefactoringOk(status); + + // file static stuff + status= checkConditions(cpp, contents.indexOf("s1"), "s2"); //$NON-NLS-1$ //$NON-NLS-2$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: s2 \n" + + "Conflicting element type: File static variable"); //$NON-NLS-1$ + + status= checkConditions(cpp, contents.indexOf("s1"), "static_other_file"); //$NON-NLS-1$ //$NON-NLS-2$ + assertRefactoringOk(status); + } + + public void testEnumeratorNameConflictsPlainC() throws Exception { + createCFwdDecls("c_fwd.h"); //$NON-NLS-1$ + createCDefs("c_def.h"); //$NON-NLS-1$ + StringWriter writer = new StringWriter(); + writer.write("#include \"c_fwd.h\" \n"); //$NON-NLS-1$ + writer.write("#include \"c_def.h\" \n"); //$NON-NLS-1$ + writer.write("enum E {v1, v2, v3}; \n"); //$NON-NLS-1$ + writer.write("static int s1; \n"); //$NON-NLS-1$ + writer.write("static int s2; \n"); //$NON-NLS-1$ + writer.write("void f(int par1){ \n"); //$NON-NLS-1$ + writer.write(" int w1=v1; \n"); //$NON-NLS-1$ + writer.write("} \n"); //$NON-NLS-1$ + String contents = writer.toString(); + IFile c= importFile("test.c", contents ); //$NON-NLS-1$ + + writer = new StringWriter(); + writer.write( "static int static_other_file; \n" ); //$NON-NLS-1$ + importFile( "other.cpp", writer.toString() ); //$NON-NLS-1$ + + + int offset1= contents.indexOf("v1"); //$NON-NLS-1$ + + // conflicting renamings + RefactoringStatus status= checkConditions(c, offset1, "w1"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Shadowing \n" + + "New element: w1 \n" + + "Conflicting element type: Local variable"); //$NON-NLS-1$ + status= checkConditions(c, contents.indexOf("w1"), "v1"); //$NON-NLS-1$ //$NON-NLS-2$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Shadowing \n" + + "New element: v1 \n" + + "Conflicting element type: Enumerator"); //$NON-NLS-1$ + status= checkConditions(c, contents.indexOf("par1"), "v1"); //$NON-NLS-1$ //$NON-NLS-2$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Shadowing \n" + + "New element: v1 \n" + + "Conflicting element type: Enumerator"); //$NON-NLS-1$ + status= checkConditions(c, offset1, "par1"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Shadowing \n" + + "New element: par1 \n" + + "Conflicting element type: Parameter"); //$NON-NLS-1$ + status= checkConditions(c, offset1, "extern_var"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: extern_var \n" + + "Conflicting element type: Global variable"); //$NON-NLS-1$ + status= checkConditions(c, offset1, "var_def"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: var_def \n" + + "Conflicting element type: Global variable"); //$NON-NLS-1$ + status= checkConditions(c, offset1, "enum_item"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: enum_item \n" + + "Conflicting element type: Enumerator"); //$NON-NLS-1$ + + // renamings conflicting with global stuff. + status= checkConditions(c, offset1, "func_proto"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: func_proto \n" + + "Conflicting element type: Global function"); //$NON-NLS-1$ + status= checkConditions(c, offset1, "func_def"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: func_def \n" + + "Conflicting element type: Global function"); //$NON-NLS-1$ + + status= checkConditions(c, offset1, "struct_fwd"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(c, offset1, "union_fwd"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(c, offset1, "struct_def"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(c, offset1, "union_def"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(c, offset1, "enum_def"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(c, offset1, "typedef_def"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(c, offset1, "st_member"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(c, offset1, "un_member"); //$NON-NLS-1$ + assertRefactoringOk(status); + } + + public void testMemberNameConflicts1() throws Exception { + createCppFwdDecls("cpp_fwd.hh"); //$NON-NLS-1$ + createCppDefs("cpp_def.hh"); //$NON-NLS-1$ + StringWriter writer = new StringWriter(); + writer.write("#include \"cpp_fwd.hh\" \n"); //$NON-NLS-1$ + writer.write("#include \"cpp_def.hh\" \n"); //$NON-NLS-1$ + writer.write("class Dummy { \n"); //$NON-NLS-1$ + writer.write(" int v1, v2, v3; \n"); //$NON-NLS-1$ + writer.write(" int member; \n"); //$NON-NLS-1$ + writer.write(" int method(int); \n"); //$NON-NLS-1$ + writer.write(" static int static_method(int); \n"); //$NON-NLS-1$ + writer.write(" static int static_member; \n"); //$NON-NLS-1$ + writer.write("}; \n"); //$NON-NLS-1$ + writer.write("void Dummy::method(int par1) { \n"); //$NON-NLS-1$ + writer.write(" { \n"); //$NON-NLS-1$ + writer.write(" int w1; v1++; \n"); //$NON-NLS-1$ + writer.write(" } \n"); //$NON-NLS-1$ + writer.write("} \n"); //$NON-NLS-1$ + writer.write("static void Dummy::static_method(int par2) { \n"); //$NON-NLS-1$ + writer.write(" { \n"); //$NON-NLS-1$ + writer.write(" int w2; v2++; \n"); //$NON-NLS-1$ + writer.write(" } \n"); //$NON-NLS-1$ + writer.write("} \n"); //$NON-NLS-1$ + String contents = writer.toString(); + IFile cpp= importFile("test.cpp", contents ); //$NON-NLS-1$ + + int offset1= contents.indexOf("v1"); //$NON-NLS-1$ + int offset2= contents.indexOf("v2"); //$NON-NLS-1$ + int offset3= contents.indexOf("v3"); //$NON-NLS-1$ + + // conflicting renamings + RefactoringStatus status= checkConditions(cpp, offset1, "w1"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Shadowing \n" + + "New element: w1 \n" + + "Conflicting element type: Local variable"); //$NON-NLS-1$ + status= checkConditions(cpp, contents.indexOf("w1"), "v1"); //$NON-NLS-1$ //$NON-NLS-2$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Shadowing \n" + + "New element: v1 \n" + + "Conflicting element type: Field"); //$NON-NLS-1$ + status= checkConditions(cpp, contents.indexOf("par1"), "v1"); //$NON-NLS-1$ //$NON-NLS-2$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Shadowing \n" + + "New element: v1 \n" + + "Conflicting element type: Field"); //$NON-NLS-1$ + status= checkConditions(cpp, offset1, "par1"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Shadowing \n" + + "New element: par1 \n" + + "Conflicting element type: Parameter"); //$NON-NLS-1$ + status= checkConditions(cpp, offset1, "extern_var"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Shadowing \n" + + "New element: extern_var \n" + + "Conflicting element type: Global variable"); //$NON-NLS-1$ + status= checkConditions(cpp, offset1, "var_def"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Shadowing \n" + + "New element: var_def \n" + + "Conflicting element type: Global variable"); //$NON-NLS-1$ + status= checkConditions(cpp, offset1, "enum_item"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Shadowing \n" + + "New element: enum_item \n" + + "Conflicting element type: Enumerator"); //$NON-NLS-1$ + + status= checkConditions(cpp, offset2, "w2"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Shadowing \n" + + "New element: w2 \n" + + "Conflicting element type: Local variable"); //$NON-NLS-1$ + status= checkConditions(cpp, offset2, "par2"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Shadowing \n" + + "New element: par2 \n" + + "Conflicting element type: Parameter"); //$NON-NLS-1$ + status= checkConditions(cpp, offset2, "extern_var"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Shadowing \n" + + "New element: extern_var \n" + + "Conflicting element type: Global variable"); //$NON-NLS-1$ + status= checkConditions(cpp, offset2, "var_def"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Shadowing \n" + + "New element: var_def \n" + + "Conflicting element type: Global variable"); //$NON-NLS-1$ + status= checkConditions(cpp, offset2, "enum_item"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Shadowing \n" + + "New element: enum_item \n" + + "Conflicting element type: Enumerator"); //$NON-NLS-1$ + + + status= checkConditions(cpp, offset2, "member"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: member \n" + + "Conflicting element type: Field"); //$NON-NLS-1$ + status= checkConditions(cpp, offset2, "method"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: method \n" + + "Conflicting element type: Method"); //$NON-NLS-1$ + status= checkConditions(cpp, offset2, "static_member"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: static_member \n" + + "Conflicting element type: Field"); //$NON-NLS-1$ + status= checkConditions(cpp, offset2, "static_method"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: static_method \n" + + "Conflicting element type: Method"); //$NON-NLS-1$ + status= checkConditions(cpp, offset3, "static_member"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: static_member \n" + + "Conflicting element type: Field"); //$NON-NLS-1$ + status= checkConditions(cpp, offset3, "static_method"); //$NON-NLS-1$ + assertRefactoringError(status, "A conflict was encountered during refactoring. \n" + + "Type of problem: Redeclaration \n" + + "New element: static_method \n" + + "Conflicting element type: Method"); //$NON-NLS-1$ + } + + public void testMemberNameConflicts2() throws Exception { + createCppFwdDecls("cpp_fwd.hh"); //$NON-NLS-1$ + createCppDefs("cpp_def.hh"); //$NON-NLS-1$ + StringWriter writer = new StringWriter(); + writer.write("#include \"cpp_fwd.hh\" \n"); //$NON-NLS-1$ + writer.write("#include \"cpp_def.hh\" \n"); //$NON-NLS-1$ + writer.write("class Dummy { \n"); //$NON-NLS-1$ + writer.write(" int v1, v2, v3; \n"); //$NON-NLS-1$ + writer.write("}; \n"); //$NON-NLS-1$ + writer.write("Dummy d; \n"); //$NON-NLS-1$ + writer.write("void f(int par1){ \n"); //$NON-NLS-1$ + writer.write(" { \n"); //$NON-NLS-1$ + writer.write(" int w1; d.v1++; \n"); //$NON-NLS-1$ + writer.write(" } \n"); //$NON-NLS-1$ + writer.write("} \n"); //$NON-NLS-1$ + writer.write("void class_def::method(int par2) { \n"); //$NON-NLS-1$ + writer.write(" { \n"); //$NON-NLS-1$ + writer.write(" int w2; d.v2++; \n"); //$NON-NLS-1$ + writer.write(" } \n"); //$NON-NLS-1$ + writer.write("} \n"); //$NON-NLS-1$ + writer.write("static void class_def::static_method(int par3) { \n"); //$NON-NLS-1$ + writer.write(" { \n"); //$NON-NLS-1$ + writer.write(" int w3; d.v3++; \n"); //$NON-NLS-1$ + writer.write(" } \n"); //$NON-NLS-1$ + writer.write("} \n"); //$NON-NLS-1$ + String contents = writer.toString(); + IFile cpp= importFile("test.cpp", contents ); //$NON-NLS-1$ + + int offset1= contents.indexOf("v1"); //$NON-NLS-1$ + int offset2= contents.indexOf("v2"); //$NON-NLS-1$ + int offset3= contents.indexOf("v3"); //$NON-NLS-1$ + + // conflicting renamings + RefactoringStatus status= checkConditions(cpp, offset1, "w1"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "par1"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "extern_var"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "var_def"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "enum_item"); //$NON-NLS-1$ + assertRefactoringOk(status); + + status= checkConditions(cpp, offset2, "w2"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset2, "par2"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset2, "extern_var"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset2, "var_def"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset2, "enum_item"); //$NON-NLS-1$ + assertRefactoringOk(status); + + status= checkConditions(cpp, offset3, "w3"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset3, "par3"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset3, "extern_var"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset3, "var_def"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset3, "enum_item"); //$NON-NLS-1$ + assertRefactoringOk(status); + + // renamings depending on scope + status= checkConditions(cpp, offset1, "member"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "method"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "static_member"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "static_method"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset2, "member"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset2, "method"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset2, "static_member"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset2, "static_method"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset3, "static_member"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset3, "static_method"); //$NON-NLS-1$ + assertRefactoringOk(status); + + status= checkConditions(cpp, offset1, "func_proto"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "func_proto_ov"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "func_def"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "func_def_ov"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset2, "func_proto"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset2, "func_proto_ov"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset2, "func_def"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset2, "func_def_ov"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset3, "func_proto"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset3, "func_proto_ov"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset3, "func_def"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset3, "func_def_ov"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "class_fwd"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "struct_fwd"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "union_fwd"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "class_def"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "struct_def"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "union_def"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "enum_def"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "typedef_def"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "namespace_def"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "st_member"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset1, "un_member"); //$NON-NLS-1$ + assertRefactoringOk(status); + + status= checkConditions(cpp, offset2, "class_fwd"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset2, "struct_fwd"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset2, "union_fwd"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset2, "class_def"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset2, "struct_def"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset2, "union_def"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset2, "enum_def"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset2, "typedef_def"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset2, "namespace_def"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset2, "st_member"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset2, "un_member"); //$NON-NLS-1$ + assertRefactoringOk(status); + + status= checkConditions(cpp, offset3, "class_fwd"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset3, "struct_fwd"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset3, "union_fwd"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset3, "class_def"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset3, "struct_def"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset3, "union_def"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset3, "enum_def"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset3, "typedef_def"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset3, "namespace_def"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset3, "st_member"); //$NON-NLS-1$ + assertRefactoringOk(status); + status= checkConditions(cpp, offset3, "un_member"); //$NON-NLS-1$ + assertRefactoringOk(status); + } + + public void testReferenceViaMacro() throws Exception { + StringWriter writer = new StringWriter(); + writer.write("#define PASSON(x) (x) \n"); //$NON-NLS-1$ + writer.write("#define INC(x) PASSON(/*pc*/x)++ \n"); //$NON-NLS-1$ + writer.write("void f() { \n"); //$NON-NLS-1$ + writer.write(" int v1; \n"); //$NON-NLS-1$ + writer.write(" INC(/*comment*/ v1); \n"); //$NON-NLS-1$ + writer.write("} \n"); //$NON-NLS-1$ + String contents = writer.toString(); + IFile cpp= importFile("test.cpp", contents ); //$NON-NLS-1$ + + int offset = contents.indexOf("v1") ; //$NON-NLS-1$ + int offset2= contents.indexOf("v1", offset+1) ; //$NON-NLS-1$ + Change changes = getRefactorChanges(cpp, offset2, "z"); //$NON-NLS-1$ + assertTotalChanges( 2, changes ); + assertChange( changes, cpp, offset, 2, "z" ); //$NON-NLS-1$ + assertChange( changes, cpp, offset2, 2, "z" ); //$NON-NLS-1$ + } + + public void testReferenceViaMacro2() throws Exception { + StringWriter writer = new StringWriter(); + writer.write("#define INC(x,y) x+=y \n"); //$NON-NLS-1$ + writer.write("void f() { \n"); //$NON-NLS-1$ + writer.write(" int v1,v2; \n"); //$NON-NLS-1$ + writer.write(" INC(v2,v1); \n"); //$NON-NLS-1$ + writer.write("} \n"); //$NON-NLS-1$ + String contents = writer.toString(); + IFile cpp= importFile("test.cpp", contents ); //$NON-NLS-1$ + + int offset = contents.indexOf("v1") ; //$NON-NLS-1$ + int offset2= contents.indexOf("v1", offset+1) ; //$NON-NLS-1$ + Change changes = getRefactorChanges(cpp, offset2, "z"); //$NON-NLS-1$ + assertTotalChanges( 2, changes ); + assertChange( changes, cpp, offset, 2, "z" ); //$NON-NLS-1$ + assertChange( changes, cpp, offset2, 2, "z" ); //$NON-NLS-1$ + } + + public void testReferenceViaMacro3() throws Exception { + StringWriter writer = new StringWriter(); + writer.write("#define INC(x,y) x+=y \n"); //$NON-NLS-1$ + writer.write("void f() { \n"); //$NON-NLS-1$ + writer.write(" int v1,v2; \n"); //$NON-NLS-1$ + writer.write(" INC(v1,v1); \n"); //$NON-NLS-1$ + writer.write("} \n"); //$NON-NLS-1$ + String contents = writer.toString(); + IFile cpp= importFile("test.cpp", contents ); //$NON-NLS-1$ + + int offset = contents.indexOf("v1") ; //$NON-NLS-1$ + Change changes = getRefactorChanges(cpp, offset, "z"); //$NON-NLS-1$ + assertTotalChanges( 3, changes ); + assertChange( changes, cpp, offset, 2, "z" ); //$NON-NLS-1$ + offset= contents.indexOf("v1", offset+1) ; //$NON-NLS-1$ + assertChange( changes, cpp, offset, 2, "z" ); //$NON-NLS-1$ + offset= contents.indexOf("v1", offset+1) ; //$NON-NLS-1$ + assertChange( changes, cpp, offset, 2, "z" ); //$NON-NLS-1$ + } + + public void testReferenceViaMacro4() throws Exception { + StringWriter writer = new StringWriter(); + writer.write("#define INC(x) v2++ \n"); //$NON-NLS-1$ + writer.write("void f() { \n"); //$NON-NLS-1$ + writer.write(" int v1; \n"); //$NON-NLS-1$ + writer.write(" INC(v1); \n"); //$NON-NLS-1$ + writer.write("} \n"); //$NON-NLS-1$ + String contents = writer.toString(); + IFile cpp= importFile("test.cpp", contents ); //$NON-NLS-1$ + + int offset = contents.indexOf("v1") ; //$NON-NLS-1$ + Change changes = getRefactorChanges(cpp, offset, "z"); //$NON-NLS-1$ + assertTotalChanges( 1, 1, 0, changes ); + assertChange( changes, cpp, offset, 2, "z" ); //$NON-NLS-1$ + } + + public void testReferenceViaMacro5() throws Exception { + StringWriter writer = new StringWriter(); + writer.write("#define INC(x) v1++ \n"); //$NON-NLS-1$ + writer.write("void f() { \n"); //$NON-NLS-1$ + writer.write(" int v1,v2; \n"); //$NON-NLS-1$ + writer.write(" INC(v2); \n"); //$NON-NLS-1$ + writer.write("} \n"); //$NON-NLS-1$ + writer.write("void f2() { \n"); //$NON-NLS-1$ + writer.write(" int v12; \n"); //$NON-NLS-1$ + writer.write(" INC(v12); \n"); //$NON-NLS-1$ + writer.write("} \n"); //$NON-NLS-1$ + String contents = writer.toString(); + IFile cpp= importFile("test.cpp", contents ); //$NON-NLS-1$ + + int offset = contents.indexOf("v1") ; //$NON-NLS-1$ + offset= contents.indexOf("v1", offset+1) ; //$NON-NLS-1$ + Change changes = getRefactorChanges(cpp, offset, "z"); //$NON-NLS-1$ + assertTotalChanges( 1, changes ); + assertChange( changes, cpp, offset, 2, "z" ); //$NON-NLS-1$ + } + + public void testBug72646() throws Exception { + StringWriter writer = new StringWriter(); + writer.write("class C2: public C1 { \n"); //$NON-NLS-1$ + writer.write(" C2(int x, int y); \n"); //$NON-NLS-1$ + writer.write(" int y; \n"); //$NON-NLS-1$ + writer.write("}; \n"); //$NON-NLS-1$ + writer.write("C2::C2(int x, int y) \n"); //$NON-NLS-1$ + writer.write(" :C1(x), y(y) {} \n"); //$NON-NLS-1$ + String contents = writer.toString(); + IFile cpp= importFile("test.cpp", contents ); //$NON-NLS-1$ + + int offset = contents.indexOf("y") ; //$NON-NLS-1$ + offset= contents.indexOf("y", offset+1) ; //$NON-NLS-1$ + Change changes = getRefactorChanges(cpp, offset, "z"); //$NON-NLS-1$ + assertTotalChanges( 2, changes ); + assertChange( changes, cpp, offset, 1, "z" ); //$NON-NLS-1$ + offset= contents.indexOf("y", offset+1) ; //$NON-NLS-1$ + offset= contents.indexOf("y", offset+1) ; //$NON-NLS-1$ + assertChange( changes, cpp, offset, 1, "z" ); //$NON-NLS-1$ + } +} diff --git a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/refactoring/rename/TestRenameParticipant.java b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/refactoring/rename/TestRenameParticipant.java new file mode 100644 index 00000000000..997526c7ae2 --- /dev/null +++ b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/refactoring/rename/TestRenameParticipant.java @@ -0,0 +1,65 @@ +/******************************************************************************* + * Copyright (c) 2005 Wind River Systems, Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Markus Schorn - initial API and implementation + ******************************************************************************/ + +package org.eclipse.cdt.ui.tests.refactoring.rename; + +import org.eclipse.core.runtime.*; +import org.eclipse.ltk.core.refactoring.*; +import org.eclipse.ltk.core.refactoring.participants.*; + +public class TestRenameParticipant extends RenameParticipant { + private static Object sElement= null; + private static RenameArguments sArguments= null; + private static int sConditionCheck= 0; + private static int sCreateChange= 0; + + public static int getConditionCheckCount() { + return sConditionCheck; + } + + public static int getCreateChangeCount() { + return sCreateChange; + } + + public static Object getElement() { + return sElement; + } + + public static RenameArguments staticGetArguments() { + return sArguments; + } + + public static void reset() { + sElement= null; + sArguments= null; + sConditionCheck= sCreateChange= 0; + } + + protected boolean initialize(Object element) { + sElement= element; + return true; + } + + public String getName() { + return "TestRenameParticipant"; //$NON-NLS-1$ + } + + public RefactoringStatus checkConditions(IProgressMonitor pm, CheckConditionsContext context) throws OperationCanceledException { + sConditionCheck++; + sArguments= getArguments(); + return new RefactoringStatus(); + } + + public Change createChange(IProgressMonitor pm) throws CoreException, OperationCanceledException { + sCreateChange++; + return null; + } +} diff --git a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/refactoring/utils/CorrectCaseTest.java b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/refactoring/utils/CorrectCaseTest.java new file mode 100644 index 00000000000..a3ae5735ec6 --- /dev/null +++ b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/refactoring/utils/CorrectCaseTest.java @@ -0,0 +1,86 @@ +/******************************************************************************* + * Copyright (c) 2008 Institute for Software, HSR Hochschule fuer Technik + * Rapperswil, University of applied sciences and others + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Institute for Software - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.ui.tests.refactoring.utils; + +import junit.framework.TestCase; + +import org.eclipse.cdt.internal.ui.refactoring.utils.IdentifierHelper; +import org.eclipse.cdt.internal.ui.refactoring.utils.IdentifierResult; + +/** + * @author Thomas Corbat + * + */ +public class CorrectCaseTest extends TestCase { + + public CorrectCaseTest(){ + super("Check Correct Identifier"); //$NON-NLS-1$ + } + + @Override + public void runTest() { + IdentifierResult result; + + result = IdentifierHelper.checkIdentifierName("A"); //$NON-NLS-1$ + assertTrue(result.getMessage(), IdentifierResult.VALID == result.getResult()); + + result = IdentifierHelper.checkIdentifierName("Z"); //$NON-NLS-1$ + assertTrue(result.getMessage(), IdentifierResult.VALID == result.getResult()); + + result = IdentifierHelper.checkIdentifierName("a"); //$NON-NLS-1$ + assertTrue(result.getMessage(), IdentifierResult.VALID == result.getResult()); + + result = IdentifierHelper.checkIdentifierName("z"); //$NON-NLS-1$ + assertTrue(result.getMessage(), IdentifierResult.VALID == result.getResult()); + + result = IdentifierHelper.checkIdentifierName("_"); //$NON-NLS-1$ + assertTrue(result.getMessage(), IdentifierResult.VALID == result.getResult()); + + result = IdentifierHelper.checkIdentifierName("_A"); //$NON-NLS-1$ + assertTrue(result.getMessage(), IdentifierResult.VALID == result.getResult()); + + result = IdentifierHelper.checkIdentifierName("_Z"); //$NON-NLS-1$ + assertTrue(result.getMessage(), IdentifierResult.VALID == result.getResult()); + + result = IdentifierHelper.checkIdentifierName("_a"); //$NON-NLS-1$ + assertTrue(result.getMessage(), IdentifierResult.VALID == result.getResult()); + + result = IdentifierHelper.checkIdentifierName("_z"); //$NON-NLS-1$ + assertTrue(result.getMessage(), IdentifierResult.VALID == result.getResult()); + + result = IdentifierHelper.checkIdentifierName("__"); //$NON-NLS-1$ + assertTrue(result.getMessage(), IdentifierResult.VALID == result.getResult()); + + result = IdentifierHelper.checkIdentifierName("_0"); //$NON-NLS-1$ + assertTrue(result.getMessage(), IdentifierResult.VALID == result.getResult()); + + result = IdentifierHelper.checkIdentifierName("_9"); //$NON-NLS-1$ + assertTrue(result.getMessage(), IdentifierResult.VALID == result.getResult()); + + result = IdentifierHelper.checkIdentifierName("Aaaa"); //$NON-NLS-1$ + assertTrue(result.getMessage(), IdentifierResult.VALID == result.getResult()); + + result = IdentifierHelper.checkIdentifierName("Zaaa"); //$NON-NLS-1$ + assertTrue(result.getMessage(), IdentifierResult.VALID == result.getResult()); + + result = IdentifierHelper.checkIdentifierName("aaaa"); //$NON-NLS-1$ + assertTrue(result.getMessage(), IdentifierResult.VALID == result.getResult()); + + result = IdentifierHelper.checkIdentifierName("zaaa"); //$NON-NLS-1$ + assertTrue(result.getMessage(), IdentifierResult.VALID == result.getResult()); + + result = IdentifierHelper.checkIdentifierName("_aaa"); //$NON-NLS-1$ + assertTrue(result.getMessage(), IdentifierResult.VALID == result.getResult()); + + } + +} diff --git a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/refactoring/utils/DigitFirstCaseTest.java b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/refactoring/utils/DigitFirstCaseTest.java new file mode 100644 index 00000000000..3367c6b5790 --- /dev/null +++ b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/refactoring/utils/DigitFirstCaseTest.java @@ -0,0 +1,47 @@ +/******************************************************************************* + * Copyright (c) 2008 Institute for Software, HSR Hochschule fuer Technik + * Rapperswil, University of applied sciences and others + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Institute for Software - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.ui.tests.refactoring.utils; + +import junit.framework.TestCase; + +import org.eclipse.cdt.internal.ui.refactoring.utils.IdentifierHelper; +import org.eclipse.cdt.internal.ui.refactoring.utils.IdentifierResult; + +/** + * @author Thomas Corbat + * + */ +public class DigitFirstCaseTest extends TestCase { + + public DigitFirstCaseTest() { + super("Check Digit First Identifier"); //$NON-NLS-1$ + } + + @Override + public void runTest() { + IdentifierResult result; + + result = IdentifierHelper.checkIdentifierName("0"); //$NON-NLS-1$ + assertTrue(result.getMessage(), IdentifierResult.DIGIT_FIRST == result.getResult()); + + result = IdentifierHelper.checkIdentifierName("9"); //$NON-NLS-1$ + assertTrue(result.getMessage(), IdentifierResult.DIGIT_FIRST == result.getResult()); + + result = IdentifierHelper.checkIdentifierName("0a"); //$NON-NLS-1$ + assertTrue(result.getMessage(), IdentifierResult.DIGIT_FIRST == result.getResult()); + + result = IdentifierHelper.checkIdentifierName("99"); //$NON-NLS-1$ + assertTrue(result.getMessage(), IdentifierResult.DIGIT_FIRST == result.getResult()); + + } + +} diff --git a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/refactoring/utils/EmptyCaseTest.java b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/refactoring/utils/EmptyCaseTest.java new file mode 100644 index 00000000000..bbb5c2a1ae6 --- /dev/null +++ b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/refactoring/utils/EmptyCaseTest.java @@ -0,0 +1,38 @@ +/******************************************************************************* + * Copyright (c) 2008 Institute for Software, HSR Hochschule fuer Technik + * Rapperswil, University of applied sciences and others + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Institute for Software - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.ui.tests.refactoring.utils; + +import junit.framework.TestCase; + +import org.eclipse.cdt.internal.ui.refactoring.utils.IdentifierHelper; +import org.eclipse.cdt.internal.ui.refactoring.utils.IdentifierResult; + +/** + * @author Thomas Corbat + * + */ +public class EmptyCaseTest extends TestCase { + + public EmptyCaseTest() { + super("Check Empty Identifier"); //$NON-NLS-1$ + } + + @Override + public void runTest() { + IdentifierResult result; + + result = IdentifierHelper.checkIdentifierName(""); //$NON-NLS-1$ + assertTrue(result.getMessage(), IdentifierResult.EMPTY == result.getResult()); + + } + +} diff --git a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/refactoring/utils/IdentifierHelperTest.java b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/refactoring/utils/IdentifierHelperTest.java new file mode 100644 index 00000000000..33e7bec0993 --- /dev/null +++ b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/refactoring/utils/IdentifierHelperTest.java @@ -0,0 +1,36 @@ +/******************************************************************************* + * Copyright (c) 2008 Institute for Software, HSR Hochschule fuer Technik + * Rapperswil, University of applied sciences and others + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Institute for Software - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.ui.tests.refactoring.utils; + +import junit.framework.Test; +import junit.framework.TestSuite; + +/** + * @author Thomas Corbat + * + */ +public class IdentifierHelperTest extends TestSuite { + + public IdentifierHelperTest() { + super("Identifier Helper Test"); //$NON-NLS-1$ + } + + public static Test suite() { + TestSuite suite = new TestSuite("Test for Identifier Helper"); //$NON-NLS-1$ + suite.addTest(new CorrectCaseTest()); + suite.addTest(new DigitFirstCaseTest()); + suite.addTest(new EmptyCaseTest()); + suite.addTest(new IllegalCharCaseTest()); + suite.addTest(new KeywordCaseTest()); + return suite; + } +} diff --git a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/refactoring/utils/IllegalCharCaseTest.java b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/refactoring/utils/IllegalCharCaseTest.java new file mode 100644 index 00000000000..0b6d2f557e3 --- /dev/null +++ b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/refactoring/utils/IllegalCharCaseTest.java @@ -0,0 +1,47 @@ +/******************************************************************************* + * Copyright (c) 2008 Institute for Software, HSR Hochschule fuer Technik + * Rapperswil, University of applied sciences and others + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Institute for Software - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.ui.tests.refactoring.utils; + +import junit.framework.TestCase; + +import org.eclipse.cdt.internal.ui.refactoring.utils.IdentifierHelper; +import org.eclipse.cdt.internal.ui.refactoring.utils.IdentifierResult; + +/** + * @author Thomas Corbat + * + */ +public class IllegalCharCaseTest extends TestCase { + + public IllegalCharCaseTest() { + super("Check Illegal Character Identifier"); //$NON-NLS-1$ + } + + @Override + public void runTest() { + IdentifierResult result; + + result = IdentifierHelper.checkIdentifierName("a~"); //$NON-NLS-1$ + assertTrue(result.getMessage(), IdentifierResult.ILLEGAL_CHARACTER == result.getResult()); + + result = IdentifierHelper.checkIdentifierName("a%"); //$NON-NLS-1$ + assertTrue(result.getMessage(), IdentifierResult.ILLEGAL_CHARACTER == result.getResult()); + + result = IdentifierHelper.checkIdentifierName("a!"); //$NON-NLS-1$ + assertTrue(result.getMessage(), IdentifierResult.ILLEGAL_CHARACTER == result.getResult()); + + result = IdentifierHelper.checkIdentifierName("{}"); //$NON-NLS-1$ + assertTrue(result.getMessage(), IdentifierResult.ILLEGAL_CHARACTER == result.getResult()); + + } + +} diff --git a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/refactoring/utils/KeywordCaseTest.java b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/refactoring/utils/KeywordCaseTest.java new file mode 100644 index 00000000000..8cfd6feea5c --- /dev/null +++ b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/refactoring/utils/KeywordCaseTest.java @@ -0,0 +1,164 @@ +/******************************************************************************* + * Copyright (c) 2008 Institute for Software, HSR Hochschule fuer Technik + * Rapperswil, University of applied sciences and others + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Institute for Software - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.ui.tests.refactoring.utils; + +import junit.framework.TestCase; + +import org.eclipse.cdt.internal.ui.refactoring.utils.IdentifierHelper; +import org.eclipse.cdt.internal.ui.refactoring.utils.IdentifierResult; + +/** + * @author Thomas Corbat + * + */ +public class KeywordCaseTest extends TestCase { + + public KeywordCaseTest() { + super("Check Keyword Identifier"); //$NON-NLS-1$ + } + + @Override + public void runTest() { + IdentifierResult result; + + result = IdentifierHelper.checkIdentifierName("using"); //$NON-NLS-1$ + assertTrue(result.getMessage(), IdentifierResult.KEYWORD == result.getResult()); + result = IdentifierHelper.checkIdentifierName("bitand"); //$NON-NLS-1$ + assertTrue(result.getMessage(), IdentifierResult.KEYWORD == result.getResult()); + result = IdentifierHelper.checkIdentifierName("for"); //$NON-NLS-1$ + assertTrue(result.getMessage(), IdentifierResult.KEYWORD == result.getResult()); + result = IdentifierHelper.checkIdentifierName("const_cast"); //$NON-NLS-1$ + assertTrue(result.getMessage(), IdentifierResult.KEYWORD == result.getResult()); + result = IdentifierHelper.checkIdentifierName("namespace"); //$NON-NLS-1$ + assertTrue(result.getMessage(), IdentifierResult.KEYWORD == result.getResult()); + result = IdentifierHelper.checkIdentifierName("break"); //$NON-NLS-1$ + assertTrue(result.getMessage(), IdentifierResult.KEYWORD == result.getResult()); + result = IdentifierHelper.checkIdentifierName("static_cast"); //$NON-NLS-1$ + assertTrue(result.getMessage(), IdentifierResult.KEYWORD == result.getResult()); + result = IdentifierHelper.checkIdentifierName("false"); //$NON-NLS-1$ + assertTrue(result.getMessage(), IdentifierResult.KEYWORD == result.getResult()); + result = IdentifierHelper.checkIdentifierName("volatile"); //$NON-NLS-1$ + assertTrue(result.getMessage(), IdentifierResult.KEYWORD == result.getResult()); + result = IdentifierHelper.checkIdentifierName("template"); //$NON-NLS-1$ + assertTrue(result.getMessage(), IdentifierResult.KEYWORD == result.getResult()); + result = IdentifierHelper.checkIdentifierName("else"); //$NON-NLS-1$ + assertTrue(result.getMessage(), IdentifierResult.KEYWORD == result.getResult()); + result = IdentifierHelper.checkIdentifierName("dynamic_cast"); //$NON-NLS-1$ + assertTrue(result.getMessage(), IdentifierResult.KEYWORD == result.getResult()); + result = IdentifierHelper.checkIdentifierName("static"); //$NON-NLS-1$ + assertTrue(result.getMessage(), IdentifierResult.KEYWORD == result.getResult()); + result = IdentifierHelper.checkIdentifierName("or"); //$NON-NLS-1$ + assertTrue(result.getMessage(), IdentifierResult.KEYWORD == result.getResult()); + result = IdentifierHelper.checkIdentifierName("not_eq"); //$NON-NLS-1$ + assertTrue(result.getMessage(), IdentifierResult.KEYWORD == result.getResult()); + result = IdentifierHelper.checkIdentifierName("class"); //$NON-NLS-1$ + assertTrue(result.getMessage(), IdentifierResult.KEYWORD == result.getResult()); + result = IdentifierHelper.checkIdentifierName("enum"); //$NON-NLS-1$ + assertTrue(result.getMessage(), IdentifierResult.KEYWORD == result.getResult()); + result = IdentifierHelper.checkIdentifierName("typedef"); //$NON-NLS-1$ + assertTrue(result.getMessage(), IdentifierResult.KEYWORD == result.getResult()); + result = IdentifierHelper.checkIdentifierName("restrict"); //$NON-NLS-1$ + assertTrue(result.getMessage(), IdentifierResult.KEYWORD == result.getResult()); + result = IdentifierHelper.checkIdentifierName("and"); //$NON-NLS-1$ + assertTrue(result.getMessage(), IdentifierResult.KEYWORD == result.getResult()); + result = IdentifierHelper.checkIdentifierName("reinterpret_cast"); //$NON-NLS-1$ + assertTrue(result.getMessage(), IdentifierResult.KEYWORD == result.getResult()); + result = IdentifierHelper.checkIdentifierName("not"); //$NON-NLS-1$ + assertTrue(result.getMessage(), IdentifierResult.KEYWORD == result.getResult()); + result = IdentifierHelper.checkIdentifierName("default"); //$NON-NLS-1$ + assertTrue(result.getMessage(), IdentifierResult.KEYWORD == result.getResult()); + result = IdentifierHelper.checkIdentifierName("explicit"); //$NON-NLS-1$ + assertTrue(result.getMessage(), IdentifierResult.KEYWORD == result.getResult()); + result = IdentifierHelper.checkIdentifierName("sizeof"); //$NON-NLS-1$ + assertTrue(result.getMessage(), IdentifierResult.KEYWORD == result.getResult()); + result = IdentifierHelper.checkIdentifierName("auto"); //$NON-NLS-1$ + assertTrue(result.getMessage(), IdentifierResult.KEYWORD == result.getResult()); + result = IdentifierHelper.checkIdentifierName("case"); //$NON-NLS-1$ + assertTrue(result.getMessage(), IdentifierResult.KEYWORD == result.getResult()); + result = IdentifierHelper.checkIdentifierName("this"); //$NON-NLS-1$ + assertTrue(result.getMessage(), IdentifierResult.KEYWORD == result.getResult()); + result = IdentifierHelper.checkIdentifierName("try"); //$NON-NLS-1$ + assertTrue(result.getMessage(), IdentifierResult.KEYWORD == result.getResult()); + result = IdentifierHelper.checkIdentifierName("friend"); //$NON-NLS-1$ + assertTrue(result.getMessage(), IdentifierResult.KEYWORD == result.getResult()); + result = IdentifierHelper.checkIdentifierName("asm"); //$NON-NLS-1$ + assertTrue(result.getMessage(), IdentifierResult.KEYWORD == result.getResult()); + result = IdentifierHelper.checkIdentifierName("virtual"); //$NON-NLS-1$ + assertTrue(result.getMessage(), IdentifierResult.KEYWORD == result.getResult()); + result = IdentifierHelper.checkIdentifierName("const"); //$NON-NLS-1$ + assertTrue(result.getMessage(), IdentifierResult.KEYWORD == result.getResult()); + result = IdentifierHelper.checkIdentifierName("or_eq"); //$NON-NLS-1$ + assertTrue(result.getMessage(), IdentifierResult.KEYWORD == result.getResult()); + result = IdentifierHelper.checkIdentifierName("catch"); //$NON-NLS-1$ + assertTrue(result.getMessage(), IdentifierResult.KEYWORD == result.getResult()); + result = IdentifierHelper.checkIdentifierName("switch"); //$NON-NLS-1$ + assertTrue(result.getMessage(), IdentifierResult.KEYWORD == result.getResult()); + result = IdentifierHelper.checkIdentifierName("goto"); //$NON-NLS-1$ + assertTrue(result.getMessage(), IdentifierResult.KEYWORD == result.getResult()); + result = IdentifierHelper.checkIdentifierName("while"); //$NON-NLS-1$ + assertTrue(result.getMessage(), IdentifierResult.KEYWORD == result.getResult()); + result = IdentifierHelper.checkIdentifierName("private"); //$NON-NLS-1$ + assertTrue(result.getMessage(), IdentifierResult.KEYWORD == result.getResult()); + result = IdentifierHelper.checkIdentifierName("throw"); //$NON-NLS-1$ + assertTrue(result.getMessage(), IdentifierResult.KEYWORD == result.getResult()); + result = IdentifierHelper.checkIdentifierName("protected"); //$NON-NLS-1$ + assertTrue(result.getMessage(), IdentifierResult.KEYWORD == result.getResult()); + result = IdentifierHelper.checkIdentifierName("struct"); //$NON-NLS-1$ + assertTrue(result.getMessage(), IdentifierResult.KEYWORD == result.getResult()); + result = IdentifierHelper.checkIdentifierName("if"); //$NON-NLS-1$ + assertTrue(result.getMessage(), IdentifierResult.KEYWORD == result.getResult()); + result = IdentifierHelper.checkIdentifierName("extern"); //$NON-NLS-1$ + assertTrue(result.getMessage(), IdentifierResult.KEYWORD == result.getResult()); + result = IdentifierHelper.checkIdentifierName("union"); //$NON-NLS-1$ + assertTrue(result.getMessage(), IdentifierResult.KEYWORD == result.getResult()); + result = IdentifierHelper.checkIdentifierName("typeid"); //$NON-NLS-1$ + assertTrue(result.getMessage(), IdentifierResult.KEYWORD == result.getResult()); + result = IdentifierHelper.checkIdentifierName("inline"); //$NON-NLS-1$ + assertTrue(result.getMessage(), IdentifierResult.KEYWORD == result.getResult()); + result = IdentifierHelper.checkIdentifierName("compl"); //$NON-NLS-1$ + assertTrue(result.getMessage(), IdentifierResult.KEYWORD == result.getResult()); + result = IdentifierHelper.checkIdentifierName("delete"); //$NON-NLS-1$ + assertTrue(result.getMessage(), IdentifierResult.KEYWORD == result.getResult()); + result = IdentifierHelper.checkIdentifierName("do"); //$NON-NLS-1$ + assertTrue(result.getMessage(), IdentifierResult.KEYWORD == result.getResult()); + result = IdentifierHelper.checkIdentifierName("xor"); //$NON-NLS-1$ + assertTrue(result.getMessage(), IdentifierResult.KEYWORD == result.getResult()); + result = IdentifierHelper.checkIdentifierName("export"); //$NON-NLS-1$ + assertTrue(result.getMessage(), IdentifierResult.KEYWORD == result.getResult()); + result = IdentifierHelper.checkIdentifierName("bitor"); //$NON-NLS-1$ + assertTrue(result.getMessage(), IdentifierResult.KEYWORD == result.getResult()); + result = IdentifierHelper.checkIdentifierName("return"); //$NON-NLS-1$ + assertTrue(result.getMessage(), IdentifierResult.KEYWORD == result.getResult()); + result = IdentifierHelper.checkIdentifierName("true"); //$NON-NLS-1$ + assertTrue(result.getMessage(), IdentifierResult.KEYWORD == result.getResult()); + result = IdentifierHelper.checkIdentifierName("operator"); //$NON-NLS-1$ + assertTrue(result.getMessage(), IdentifierResult.KEYWORD == result.getResult()); + result = IdentifierHelper.checkIdentifierName("register"); //$NON-NLS-1$ + assertTrue(result.getMessage(), IdentifierResult.KEYWORD == result.getResult()); + result = IdentifierHelper.checkIdentifierName("new"); //$NON-NLS-1$ + assertTrue(result.getMessage(), IdentifierResult.KEYWORD == result.getResult()); + result = IdentifierHelper.checkIdentifierName("and_eq"); //$NON-NLS-1$ + assertTrue(result.getMessage(), IdentifierResult.KEYWORD == result.getResult()); + result = IdentifierHelper.checkIdentifierName("typename"); //$NON-NLS-1$ + assertTrue(result.getMessage(), IdentifierResult.KEYWORD == result.getResult()); + result = IdentifierHelper.checkIdentifierName("continue"); //$NON-NLS-1$ + assertTrue(result.getMessage(), IdentifierResult.KEYWORD == result.getResult()); + result = IdentifierHelper.checkIdentifierName("mutable"); //$NON-NLS-1$ + assertTrue(result.getMessage(), IdentifierResult.KEYWORD == result.getResult()); + result = IdentifierHelper.checkIdentifierName("xor_eq"); //$NON-NLS-1$ + assertTrue(result.getMessage(), IdentifierResult.KEYWORD == result.getResult()); + result = IdentifierHelper.checkIdentifierName("public"); //$NON-NLS-1$ + assertTrue(result.getMessage(), IdentifierResult.KEYWORD == result.getResult()); + + } + +} diff --git a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/refactoring/utils/TranslationUnitHelperTest.java b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/refactoring/utils/TranslationUnitHelperTest.java new file mode 100644 index 00000000000..7c99fcdf1c9 --- /dev/null +++ b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/refactoring/utils/TranslationUnitHelperTest.java @@ -0,0 +1,51 @@ +/******************************************************************************* + * Copyright (c) 2008 Institute for Software, HSR Hochschule fuer Technik + * Rapperswil, University of applied sciences and others + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Institute for Software - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.ui.tests.refactoring.utils; + +import java.util.Properties; +import java.util.Vector; + +import org.eclipse.core.resources.IFile; + +import org.eclipse.cdt.core.dom.ast.IASTNode; +import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit; +import org.eclipse.cdt.ui.tests.refactoring.RefactoringTest; +import org.eclipse.cdt.ui.tests.refactoring.TestSourceFile; + +import org.eclipse.cdt.internal.ui.refactoring.utils.TranslationUnitHelper; + +/** + * @author Mirko Stocker + * + */ +public class TranslationUnitHelperTest extends RefactoringTest { + + private int offset; + + public TranslationUnitHelperTest(String name,Vector files) { + super(name, files); + } + + @Override + protected void runTest() throws Throwable { + IFile file = project.getFile(fileName); + IASTTranslationUnit unit = TranslationUnitHelper.loadTranslationUnit(file); + IASTNode firstNode = TranslationUnitHelper.getFirstNode(unit); + assertEquals(offset, firstNode.getNodeLocations()[0].getNodeOffset()); + } + + @Override + protected void configureRefactoring(Properties refactoringProperties) { + String offsetKind = (System.getProperty("line.separator").equals("\n")) ? "offset_unix" : "offset_win"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ + offset = new Integer(refactoringProperties.getProperty(offsetKind, "0")).intValue(); //$NON-NLS-1$ + } +} diff --git a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/refactoring/utils/UtilTestSuite.java b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/refactoring/utils/UtilTestSuite.java new file mode 100644 index 00000000000..b7270e19e01 --- /dev/null +++ b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/refactoring/utils/UtilTestSuite.java @@ -0,0 +1,31 @@ +/******************************************************************************* + * Copyright (c) 2008 Institute for Software, HSR Hochschule fuer Technik + * Rapperswil, University of applied sciences and others + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Institute for Software - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.ui.tests.refactoring.utils; + +import junit.framework.Test; +import junit.framework.TestSuite; + +import org.eclipse.cdt.ui.tests.refactoring.RefactoringTester; + +/** + * @author Thomas Corbat + * + */ +public class UtilTestSuite { + + public static Test suite() throws Exception { + TestSuite suite = new TestSuite("UtilTests"); //$NON-NLS-1$ + suite.addTest(IdentifierHelperTest.suite()); + suite.addTest(RefactoringTester.suite("TranslationUnitHelperTest", "resources/refactoring/TranslationunitHelper.rts")); //$NON-NLS-1$ //$NON-NLS-2$ + return suite; + } +} diff --git a/core/org.eclipse.cdt.ui/META-INF/MANIFEST.MF b/core/org.eclipse.cdt.ui/META-INF/MANIFEST.MF index d7a738d42a8..1fb28426ea0 100644 --- a/core/org.eclipse.cdt.ui/META-INF/MANIFEST.MF +++ b/core/org.eclipse.cdt.ui/META-INF/MANIFEST.MF @@ -28,6 +28,11 @@ Export-Package: org.eclipse.cdt.internal.corext;x-internal:=true, org.eclipse.cdt.internal.ui.navigator, org.eclipse.cdt.internal.ui.preferences;x-internal:=true, org.eclipse.cdt.internal.ui.preferences.formatter, + org.eclipse.cdt.internal.ui.refactoring;x-friends:="org.eclipse.cdt.ui.tests", + org.eclipse.cdt.internal.ui.refactoring.dialogs, + org.eclipse.cdt.internal.ui.refactoring.extractconstant;x-friends:="org.eclipse.cdt.ui.tests", + org.eclipse.cdt.internal.ui.refactoring.rename;x-friends:="org.eclipse.cdt.ui.tests", + org.eclipse.cdt.internal.ui.refactoring.utils;x-friends:="org.eclipse.cdt.ui.tests", org.eclipse.cdt.internal.ui.search;x-internal:=true, org.eclipse.cdt.internal.ui.search.actions;x-internal:=true, org.eclipse.cdt.internal.ui.text;x-internal:=true, @@ -52,6 +57,8 @@ Export-Package: org.eclipse.cdt.internal.corext;x-internal:=true, org.eclipse.cdt.ui.browser.typeinfo, org.eclipse.cdt.ui.dialogs, org.eclipse.cdt.ui.newui, + org.eclipse.cdt.ui.refactoring, + org.eclipse.cdt.ui.refactoring.actions, org.eclipse.cdt.ui.templateengine, org.eclipse.cdt.ui.templateengine.event, org.eclipse.cdt.ui.templateengine.pages, @@ -61,8 +68,8 @@ Export-Package: org.eclipse.cdt.internal.corext;x-internal:=true, org.eclipse.cdt.ui.text.c.hover, org.eclipse.cdt.ui.text.contentassist, org.eclipse.cdt.ui.text.doctools, - org.eclipse.cdt.ui.text.doctools.generic, org.eclipse.cdt.ui.text.doctools.doxygen, + org.eclipse.cdt.ui.text.doctools.generic, org.eclipse.cdt.ui.text.folding, org.eclipse.cdt.ui.wizards, org.eclipse.cdt.ui.wizards.conversion, @@ -82,9 +89,10 @@ Require-Bundle: org.eclipse.ui.ide;bundle-version="[3.3.0,4.0.0)", org.eclipse.core.runtime;bundle-version="[3.2.0,4.0.0)", org.eclipse.help;bundle-version="[3.2.0,4.0.0)", org.eclipse.ui.navigator;bundle-version="[3.2.0,4.0.0)", - org.eclipse.cdt.refactoring;bundle-version="[5.0.0,6.0.0)", org.eclipse.core.filesystem;bundle-version="[1.1.0,2.0.0)", - org.eclipse.core.variables;bundle-version="[3.1.100,4.0.0)" + org.eclipse.core.variables;bundle-version="[3.1.100,4.0.0)", + org.eclipse.ltk.core.refactoring;bundle-version="3.4.0", + org.eclipse.ltk.ui.refactoring;bundle-version="3.4.0" Bundle-ActivationPolicy: lazy Bundle-RequiredExecutionEnvironment: J2SE-1.5 Import-Package: com.ibm.icu.text diff --git a/core/org.eclipse.cdt.ui/plugin.properties b/core/org.eclipse.cdt.ui/plugin.properties index 92038b04d7d..27c24ab2c36 100644 --- a/core/org.eclipse.cdt.ui/plugin.properties +++ b/core/org.eclipse.cdt.ui/plugin.properties @@ -128,6 +128,24 @@ ActionDefinition.forwardMacroExpansion.description= Step forward in macro expans ActionDefinition.showMacroExplorer.name= Explore Macro Expansion ActionDefinition.showMacroExplorer.description= Opens a quick view for macro expansion exploration +category.refactoring.description= C/C++ Refactorings +category.refactoring.name = Refactor - C++ +refactoringExtractConstant.label = Extract Constant... + + +ActionDefinition.renameElement.name= Rename - Refactoring +ActionDefinition.renameElement.description= Rename the selected element +ActionDefinition.extractConstant.name= Extract Constant - Refactoring +ActionDefinition.extractConstant.description= Extract a constant for the selected expression + +# Action Set +CodingActionSet.label= C/C++ Coding +CodingActionSet.description= Action set containing coding related C/C++ actions + +Refactoring.menu.label= Refac&tor +Refactoring.renameAction.label=Re&name... +Refactoring.extractConstant.label=Extr&act Constant... + CEditor.name=C/C++ Editor CPluginPreferencePage.name=C/C++ @@ -198,7 +216,6 @@ CEditorPresentationActionSet.description=Actions to customize the C/C++ editor p # Menus searchMenu.label= Se&arch -refactoringMenu.label= Re&factor # Open Element OpenTypeAction.label= Open &Element... diff --git a/core/org.eclipse.cdt.ui/plugin.xml b/core/org.eclipse.cdt.ui/plugin.xml index 264f2ce2451..d6cb8fc5423 100644 --- a/core/org.eclipse.cdt.ui/plugin.xml +++ b/core/org.eclipse.cdt.ui/plugin.xml @@ -234,6 +234,7 @@ + @@ -1124,6 +1125,39 @@ + + + + + + + + + + + + + + + + + + + @@ -1714,6 +1763,27 @@ description="%ActionDefinition.showMacroExplorer.description" categoryId="org.eclipse.cdt.ui.category.source" id="org.eclipse.cdt.ui.edit.open.quick.macro.explorer"/> + + + + + + + + + + + + + + + + + + + + + + + + fHistoryEntries= new ArrayList(MAX_HISTORY_SIZE); // widgets private PageBook fPagebook; @@ -136,7 +135,8 @@ public class CHViewPart extends ViewPart { private IContextActivation fContextActivation; - public void setFocus() { + @Override + public void setFocus() { fPagebook.setFocus(); } @@ -192,6 +192,7 @@ public class CHViewPart extends ViewPart { return false; } + @Override public void createPartControl(Composite parent) { fPagebook = new PageBook(parent, SWT.NULL); fPagebook.setLayoutData(new GridData(GridData.FILL_BOTH)); @@ -214,6 +215,7 @@ public class CHViewPart extends ViewPart { } } + @Override public void dispose() { if (fContextActivation != null) { IContextService ctxService = (IContextService)getSite().getService(IContextService.class); @@ -267,13 +269,15 @@ public class CHViewPart extends ViewPart { updateSorter(); } - public void init(IViewSite site, IMemento memento) throws PartInitException { + @Override + public void init(IViewSite site, IMemento memento) throws PartInitException { fMemento= memento; super.init(site, memento); } - public void saveState(IMemento memento) { + @Override + public void saveState(IMemento memento) { if (fWorkingSetFilterUI != null) { fWorkingSetFilterUI.saveState(memento, KEY_WORKING_SET_FILTER); } @@ -341,17 +345,20 @@ public class CHViewPart extends ViewPart { fRefactoringActionGroup= new CRefactoringActionGroup(this); fWorkingSetFilterUI= new WorkingSetFilterUI(this, fMemento, KEY_WORKING_SET_FILTER) { - protected void onWorkingSetChange() { + @Override + protected void onWorkingSetChange() { updateWorkingSetFilter(this); } - protected void onWorkingSetNameChange() { + @Override + protected void onWorkingSetNameChange() { updateDescription(); } }; fReferencedByAction= new Action(CHMessages.CHViewPart_ShowCallers_label, IAction.AS_RADIO_BUTTON) { - public void run() { + @Override + public void run() { if (isChecked()) { onSetShowReferencedBy(true); } @@ -362,7 +369,8 @@ public class CHViewPart extends ViewPart { fMakesReferenceToAction= new Action(CHMessages.CHViewPart_ShowCallees_label, IAction.AS_RADIO_BUTTON) { - public void run() { + @Override + public void run() { if (isChecked()) { onSetShowReferencedBy(false); } @@ -372,7 +380,8 @@ public class CHViewPart extends ViewPart { CPluginImages.setImageDescriptors(fMakesReferenceToAction, CPluginImages.T_LCL, CPluginImages.IMG_ACTION_SHOW_RELATES_TO); fVariableFilter= new ViewerFilter() { - public boolean select(Viewer viewer, Object parentElement, Object element) { + @Override + public boolean select(Viewer viewer, Object parentElement, Object element) { if (element instanceof CHNode) { CHNode node= (CHNode) element; return !node.isVariableOrEnumerator(); @@ -381,7 +390,8 @@ public class CHViewPart extends ViewPart { } }; fFilterVariablesAction= new Action(CHMessages.CHViewPart_FilterVariables_label, IAction.AS_CHECK_BOX) { - public void run() { + @Override + public void run() { if (isChecked()) { fTreeViewer.addFilter(fVariableFilter); } @@ -392,38 +402,18 @@ public class CHViewPart extends ViewPart { }; fFilterVariablesAction.setToolTipText(CHMessages.CHViewPart_FilterVariables_tooltip); CPluginImages.setImageDescriptors(fFilterVariablesAction, CPluginImages.T_LCL, CPluginImages.IMG_ACTION_HIDE_FIELDS); - -// fMacroFilter= new ViewerFilter() { -// public boolean select(Viewer viewer, Object parentElement, Object element) { -// if (element instanceof CHNode) { -// CHNode node= (CHNode) element; -// return !node.isMacro(); -// } -// return true; -// } -// }; -// fFilterMacrosAction= new Action(CHMessages.CHViewPart_HideMacros_label, IAction.AS_CHECK_BOX) { -// public void run() { -// if (isChecked()) { -// fTreeViewer.addFilter(fMacroFilter); -// } -// else { -// fTreeViewer.removeFilter(fMacroFilter); -// } -// } -// }; -// fFilterMacrosAction.setToolTipText(CHMessages.CHViewPart_HideMacros_tooltip); -// CPluginImages.setImageDescriptors(fFilterMacrosAction, CPluginImages.T_LCL, CPluginImages.IMG_ACTION_HIDE_MACROS); fSorterAlphaNumeric= new ViewerComparator(); fSorterReferencePosition= new ViewerComparator() { - public int category(Object element) { + @Override + public int category(Object element) { if (element instanceof CHNode) { return 0; } return 1; } - public int compare(Viewer viewer, Object e1, Object e2) { + @Override + public int compare(Viewer viewer, Object e1, Object e2) { if (!(e1 instanceof CHNode)) { if (!(e2 instanceof CHNode)) { return 0; @@ -442,26 +432,30 @@ public class CHViewPart extends ViewPart { }; fShowReference= new Action(CHMessages.CHViewPart_ShowReference_label) { - public void run() { + @Override + public void run() { onShowSelectedReference(fTreeViewer.getSelection()); } }; fShowReference.setToolTipText(CHMessages.CHViewPart_ShowReference_tooltip); fOpenElement= new Action(CHMessages.CHViewPart_Open_label) { - public void run() { + @Override + public void run() { onOpenElement(fTreeViewer.getSelection()); } }; fOpenElement.setToolTipText(CHMessages.CHViewPart_Open_tooltip); fShowFilesInLabelsAction= new Action(CHMessages.CHViewPart_ShowFiles_label, IAction.AS_CHECK_BOX) { - public void run() { + @Override + public void run() { onShowFilesInLabels(isChecked()); } }; fShowFilesInLabelsAction.setToolTipText(CHMessages.CHViewPart_ShowFiles_tooltip); fNextAction = new Action(CHMessages.CHViewPart_NextReference_label) { - public void run() { + @Override + public void run() { onNextOrPrevious(true); } }; @@ -469,7 +463,8 @@ public class CHViewPart extends ViewPart { CPluginImages.setImageDescriptors(fNextAction, CPluginImages.T_LCL, CPluginImages.IMG_SHOW_NEXT); fPreviousAction = new Action(CHMessages.CHViewPart_PreviousReference_label) { - public void run() { + @Override + public void run() { onNextOrPrevious(false); } }; @@ -477,7 +472,8 @@ public class CHViewPart extends ViewPart { CPluginImages.setImageDescriptors(fPreviousAction, CPluginImages.T_LCL, CPluginImages.IMG_SHOW_PREV); fRefreshAction = new Action(CHMessages.CHViewPart_Refresh_label) { - public void run() { + @Override + public void run() { onRefresh(); } }; @@ -705,6 +701,7 @@ public class CHViewPart extends ViewPart { String label= Messages.format(CHMessages.CHViewPart_FocusOn_label, CElementLabels.getTextLabel(element, CElementBaseLabels.ALL_FULLY_QUALIFIED | CElementBaseLabels.M_PARAMETER_TYPES)); menu.appendToGroup(IContextMenuConstants.GROUP_OPEN, new Action(label) { + @Override public void run() { setInput(element); } @@ -784,7 +781,7 @@ public class CHViewPart extends ViewPart { } public ICElement[] getHistoryEntries() { - return (ICElement[]) fHistoryEntries.toArray(new ICElement[fHistoryEntries.size()]); + return fHistoryEntries.toArray(new ICElement[fHistoryEntries.size()]); } public void setHistoryEntries(ICElement[] remaining) { diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/cview/MainActionGroup.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/cview/MainActionGroup.java index 9c7fa474800..11f6b85deeb 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/cview/MainActionGroup.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/cview/MainActionGroup.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2007 IBM Corporation and others. + * Copyright (c) 2000, 2008 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -39,9 +39,9 @@ import org.eclipse.ui.ide.IDEActionFactory; import org.eclipse.cdt.core.model.ICProject; import org.eclipse.cdt.core.model.ITranslationUnit; -import org.eclipse.cdt.refactoring.actions.CRefactoringActionGroup; import org.eclipse.cdt.ui.actions.CustomFiltersActionGroup; import org.eclipse.cdt.ui.actions.OpenViewActionGroup; +import org.eclipse.cdt.ui.refactoring.actions.CRefactoringActionGroup; import org.eclipse.cdt.internal.ui.IContextMenuConstants; import org.eclipse.cdt.internal.ui.actions.SelectionConverter; @@ -91,6 +91,7 @@ public class MainActionGroup extends CViewActionGroup { /** * Handles key events in viewer. */ + @Override public void handleKeyPressed(KeyEvent event) { refactorGroup.handleKeyPressed(event); openFileGroup.handleKeyPressed(event); @@ -102,6 +103,7 @@ public class MainActionGroup extends CViewActionGroup { /** * Handles key events in viewer. */ + @Override public void handleKeyReleased(KeyEvent event) { refactorGroup.handleKeyReleased(event); openFileGroup.handleKeyReleased(event); @@ -110,6 +112,7 @@ public class MainActionGroup extends CViewActionGroup { buildGroup.handleKeyReleased(event); } + @Override protected void makeActions() { final Viewer viewer = getCView().getViewer(); IShellProvider shellProvider = getCView().getViewSite(); @@ -147,8 +150,8 @@ public class MainActionGroup extends CViewActionGroup { workingSetGroup.setWorkingSet(getCView().getWorkingSet()); fCustomFiltersActionGroup= new CustomFiltersActionGroup(getCView(), getCView().getViewer()); - addBookmarkAction = new AddBookmarkAction(shell); - addTaskAction = new AddTaskAction(shell); + addBookmarkAction = new AddBookmarkAction(shellProvider, true); + addTaskAction = new AddTaskAction(shellProvider); // Importing/exporting. importAction = new ImportResourcesAction(getCView().getSite().getWorkbenchWindow()); @@ -170,6 +173,7 @@ public class MainActionGroup extends CViewActionGroup { * Called when the context menu is about to open. Override to add your own * context dependent menu contributions. */ + @Override public void fillContextMenu(IMenuManager menu) { IStructuredSelection celements = (IStructuredSelection) getCView().getViewer().getSelection(); IStructuredSelection resources = SelectionConverter.convertSelectionToResources(celements); @@ -233,6 +237,7 @@ public class MainActionGroup extends CViewActionGroup { * Extends the superclass implementation to set the context in the * subgroups. */ + @Override public void setContext(ActionContext context) { super.setContext(context); gotoGroup.setContext(context); @@ -276,6 +281,7 @@ public class MainActionGroup extends CViewActionGroup { } } + @Override public void runDefaultAction(IStructuredSelection selection) { openFileGroup.runDefaultAction(selection); openProjectGroup.runDefaultAction(selection); @@ -291,6 +297,7 @@ public class MainActionGroup extends CViewActionGroup { * if the selection in the viewer hasn't. E.g. A project was opened or * closed. */ + @Override public void updateActionBars() { IStructuredSelection selection = (IStructuredSelection) getContext().getSelection(); @@ -311,6 +318,7 @@ public class MainActionGroup extends CViewActionGroup { crefactoringActionGroup.updateActionBars(); } + @Override public void fillActionBars(IActionBars actionBars) { actionBars.setGlobalActionHandler(IDEActionFactory.BOOKMARK.getId(), addBookmarkAction); actionBars.setGlobalActionHandler(IDEActionFactory.ADD_TASK.getId(), addTaskAction); @@ -339,11 +347,13 @@ public class MainActionGroup extends CViewActionGroup { //---- Persistent state ----------------------------------------------------------------------- + @Override public void restoreFilterAndSorterState(IMemento memento) { //fWorkingSetFilterActionGroup.restoreState(memento); fCustomFiltersActionGroup.restoreState(memento); } + @Override public void saveFilterAndSorterState(IMemento memento) { //fWorkingSetFilterActionGroup.saveState(memento); fCustomFiltersActionGroup.saveState(memento); @@ -353,6 +363,7 @@ public class MainActionGroup extends CViewActionGroup { return fCustomFiltersActionGroup; } + @Override public void dispose() { importAction.dispose(); exportAction.dispose(); diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/AbstractCModelOutlinePage.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/AbstractCModelOutlinePage.java index 490b3b9c6c1..e81072806bd 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/AbstractCModelOutlinePage.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/AbstractCModelOutlinePage.java @@ -138,7 +138,7 @@ public abstract class AbstractCModelOutlinePage extends Page implements IContent public IncludeGroupingAction(AbstractCModelOutlinePage outlinePage) { super(ActionMessages.getString("IncludesGroupingAction.label")); //$NON-NLS-1$ setDescription(ActionMessages.getString("IncludesGroupingAction.description")); //$NON-NLS-1$ - setToolTipText(ActionMessages.getString("IncludeGroupingAction.tooltip")); //$NON-NLS-1$ + setToolTipText(ActionMessages.getString("IncludesGroupingAction.tooltip")); //$NON-NLS-1$ CPluginImages.setImageDescriptors(this, CPluginImages.T_LCL, CPluginImages.IMG_MENU_GROUP_INCLUDE); boolean enabled= isIncludesGroupingEnabled(); @@ -149,6 +149,7 @@ public abstract class AbstractCModelOutlinePage extends Page implements IContent /** * Runs the action. */ + @Override public void run() { PreferenceConstants.getPreferenceStore().setValue(PreferenceConstants.OUTLINE_GROUP_INCLUDES, isChecked()); } @@ -177,6 +178,7 @@ public abstract class AbstractCModelOutlinePage extends Page implements IContent /** * Runs the action. */ + @Override public void run() { boolean checked = isChecked(); PreferenceConstants.getPreferenceStore().setValue(PreferenceConstants.OUTLINE_LINK_TO_EDITOR, checked); @@ -301,6 +303,7 @@ public abstract class AbstractCModelOutlinePage extends Page implements IContent return fTreeViewer; } + @Override public void createControl(Composite parent) { fTreeViewer = createTreeViewer(parent); initDragAndDrop(); @@ -344,6 +347,7 @@ public abstract class AbstractCModelOutlinePage extends Page implements IContent PlatformUI.getWorkbench().getHelpSystem().setHelp(control, ICHelpContextIds.COUTLINE_VIEW); } + @Override public void dispose() { if (fTreeViewer != null) { fTreeViewer.removeSelectionChangedListener(this); @@ -498,6 +502,7 @@ public abstract class AbstractCModelOutlinePage extends Page implements IContent } } + @Override public Control getControl() { if (fTreeViewer == null) return null; @@ -531,6 +536,7 @@ public abstract class AbstractCModelOutlinePage extends Page implements IContent /** * Sets focus to a part in the page. */ + @Override public void setFocus() { fTreeViewer.getControl().setFocus(); } diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/CContentOutlinePage.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/CContentOutlinePage.java index 50ab6a64b52..cdb5e1f0715 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/CContentOutlinePage.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/CContentOutlinePage.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2005, 2007 IBM Corporation and others. + * Copyright (c) 2005, 2008 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -15,10 +15,10 @@ package org.eclipse.cdt.internal.ui.editor; import org.eclipse.ui.actions.ActionGroup; -import org.eclipse.cdt.refactoring.actions.CRefactoringActionGroup; import org.eclipse.cdt.ui.actions.CustomFiltersActionGroup; import org.eclipse.cdt.ui.actions.MemberFilterActionGroup; import org.eclipse.cdt.ui.actions.OpenViewActionGroup; +import org.eclipse.cdt.ui.refactoring.actions.CRefactoringActionGroup; import org.eclipse.cdt.internal.ui.search.actions.SelectionSearchGroup; @@ -40,24 +40,29 @@ public class CContentOutlinePage extends AbstractCModelOutlinePage { return (CEditor)fEditor; } + @Override protected SelectionSearchGroup createSearchActionGroup() { return new SelectionSearchGroup(this); } + @Override protected OpenViewActionGroup createOpenViewActionGroup() { OpenViewActionGroup ovag= new OpenViewActionGroup(this); ovag.setEnableIncludeBrowser(true); return ovag; } + @Override protected ActionGroup createRefactoringActionGroup() { return new CRefactoringActionGroup(this); } + @Override protected ActionGroup createCustomFiltersActionGroup() { return new CustomFiltersActionGroup("org.eclipse.cdt.ui.COutlinePage", getTreeViewer()); //$NON-NLS-1$ } + @Override protected ActionGroup createMemberFilterActionGroup() { return new MemberFilterActionGroup(getTreeViewer(), "COutlineViewer"); //$NON-NLS-1$ } diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/CEditor.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/CEditor.java index a68a265f537..e5e77d725ba 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/CEditor.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/CEditor.java @@ -172,12 +172,12 @@ import org.eclipse.cdt.core.model.ISourceRange; import org.eclipse.cdt.core.model.ISourceReference; import org.eclipse.cdt.core.model.ITranslationUnit; import org.eclipse.cdt.core.model.IWorkingCopy; -import org.eclipse.cdt.refactoring.actions.CRefactoringActionGroup; import org.eclipse.cdt.ui.CUIPlugin; import org.eclipse.cdt.ui.IWorkingCopyManager; import org.eclipse.cdt.ui.PreferenceConstants; import org.eclipse.cdt.ui.actions.GenerateActionGroup; import org.eclipse.cdt.ui.actions.OpenViewActionGroup; +import org.eclipse.cdt.ui.refactoring.actions.CRefactoringActionGroup; import org.eclipse.cdt.ui.text.ICPartitions; import org.eclipse.cdt.ui.text.folding.ICFoldingStructureProvider; diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/ICEditorActionDefinitionIds.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/ICEditorActionDefinitionIds.java index 069ba1444a8..31975edd089 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/ICEditorActionDefinitionIds.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/ICEditorActionDefinitionIds.java @@ -80,13 +80,6 @@ public interface ICEditorActionDefinitionIds extends ITextEditorActionDefinition */ public static final String OPEN_DECL= "org.eclipse.cdt.ui.edit.opendecl"; //$NON-NLS-1$ - /** - * Action definition ID of the open definition action - * (value "org.eclipse.cdt.ui.edit.opendef"). - * @deprecated see bug 167162 - */ - public static final String OPEN_DEF= "org.eclipse.cdt.ui.edit.opendef"; //$NON-NLS-1$ - /** * Action definition ID of the show in C/C++ Projects View action * (value "org.eclipse.cdt.ui.edit.opencview"). @@ -98,7 +91,13 @@ public interface ICEditorActionDefinitionIds extends ITextEditorActionDefinition * (value "org.eclipse.cdt.ui.edit.text.rename.element"). */ public static final String RENAME_ELEMENT= "org.eclipse.cdt.ui.edit.text.rename.element"; //$NON-NLS-1$ - + + /** + * Action definition ID of the refactor -> extract constant action + * (value "org.eclipse.cdt.ui.refactor.extract.constant"). + */ + public static final String EXTRACT_CONSTANT= "org.eclipse.cdt.ui.refactor.extract.constant"; //$NON-NLS-1$ + /** * Action definition ID of the refactor -> undo action * (value "org.eclipse.cdt.ui.edit.text.undo.action"). diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/includebrowser/IBMessages.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/includebrowser/IBMessages.java index 6bf86430078..56c4b03aca2 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/includebrowser/IBMessages.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/includebrowser/IBMessages.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2006, 2007 Wind River Systems, Inc. and others. + * Copyright (c) 2006, 2008 Wind River Systems, Inc. and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -8,7 +8,6 @@ * Contributors: * Markus Schorn - initial API and implementation *******************************************************************************/ - package org.eclipse.cdt.internal.ui.includebrowser; import org.eclipse.osgi.util.NLS; @@ -35,7 +34,6 @@ public class IBMessages extends NLS { public static String IBViewPart_jobCheckInput; public static String IBViewPart_nextMatch_label; public static String IBViewPart_nextMatch_tooltip; - public static String IBViewPart_OpenWithMenu_label; public static String IBViewPart_previousMatch_label; public static String IBViewPart_previousMatch_tooltip; public static String IBViewPart_refresh_label; diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/includebrowser/IBMessages.properties b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/includebrowser/IBMessages.properties index 0441999d969..2e945d47a6d 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/includebrowser/IBMessages.properties +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/includebrowser/IBMessages.properties @@ -1,12 +1,12 @@ ############################################################################### -# Copyright (c) 2006, 2007 Wind River Systems, Inc and others. +# Copyright (c) 2006, 2008 Wind River Systems, Inc and others. # All rights reserved. This program and the accompanying materials # are made available under the terms of the Eclipse Public License v1.0 # which accompanies this distribution, and is available at # http://www.eclipse.org/legal/epl-v10.html # # Contributors: -# Markus Schorn - Initial API and implementation +# Markus Schorn - Initial API and implementation ############################################################################### IBViewPart_instructionMessage=To display an include hierarchy, drop a c/c++-file onto this view. @@ -23,7 +23,6 @@ IBViewPart_IncludedByContentDescription=Files including ''{0}'' - in {1} IBViewPart_IncludesToContentDescription=Files included by ''{0}'' - in {1} IBViewPart_hideInactive_tooltip=Hide Includes from Inactive Code IBViewPart_previousMatch_tooltip=Show Previous Include -IBViewPart_OpenWithMenu_label=Open With IBViewPart_hideInactive_label=Hide Inactive Includes IBViewPart_hideSystem_tooltip=Hide System Includes IBViewPart_ShowInMenu_label=Show In diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/includebrowser/IBViewPart.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/includebrowser/IBViewPart.java index 2c2299c1f5b..5c1e7e80c6b 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/includebrowser/IBViewPart.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/includebrowser/IBViewPart.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2006, 2007 Wind River Systems, Inc. and others. + * Copyright (c) 2006, 2008 Wind River Systems, Inc. and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -9,7 +9,6 @@ * Markus Schorn - initial API and implementation * Ed Swartz (Nokia) *******************************************************************************/ - package org.eclipse.cdt.internal.ui.includebrowser; import java.util.ArrayList; @@ -113,7 +112,7 @@ public class IBViewPart extends ViewPart private IMemento fMemento; private boolean fShowsMessage; private IBNode fLastNavigationNode; - private ArrayList fHistoryEntries= new ArrayList(MAX_HISTORY_SIZE); + private ArrayList fHistoryEntries= new ArrayList(MAX_HISTORY_SIZE); // widgets private PageBook fPagebook; @@ -147,7 +146,8 @@ public class IBViewPart extends ViewPart private IBSetInputJob fSetInputJob; - public void setFocus() { + @Override + public void setFocus() { fPagebook.setFocus(); } @@ -206,6 +206,7 @@ public class IBViewPart extends ViewPart updateDescription(); final Display display= Display.getCurrent(); Job job= new Job(IBMessages.IBViewPart_jobCheckInput) { + @Override protected IStatus run(IProgressMonitor monitor) { try { IIndex index= CCorePlugin.getIndexManager().getIndex(input.getCProject()); @@ -246,6 +247,7 @@ public class IBViewPart extends ViewPart fRefreshAction.setEnabled(!fShowsMessage); } + @Override public void createPartControl(Composite parent) { fSetInputJob= new IBSetInputJob(this, Display.getCurrent()); @@ -271,6 +273,7 @@ public class IBViewPart extends ViewPart } } + @Override public void dispose() { if (fContextActivation != null) { IContextService ctxService = (IContextService)getSite().getService(IContextService.class); @@ -329,13 +332,15 @@ public class IBViewPart extends ViewPart } - public void init(IViewSite site, IMemento memento) throws PartInitException { + @Override + public void init(IViewSite site, IMemento memento) throws PartInitException { fMemento= memento; super.init(site, memento); } - public void saveState(IMemento memento) { + @Override + public void saveState(IMemento memento) { if (fWorkingSetFilter != null) { fWorkingSetFilter.getUI().saveState(memento, KEY_WORKING_SET_FILTER); } @@ -410,17 +415,20 @@ public class IBViewPart extends ViewPart private void createActions() { fWorkingSetFilterUI= new WorkingSetFilterUI(this, fMemento, KEY_WORKING_SET_FILTER) { - protected void onWorkingSetChange() { + @Override + protected void onWorkingSetChange() { updateWorkingSetFilter(this); } - protected void onWorkingSetNameChange() { + @Override + protected void onWorkingSetNameChange() { updateDescription(); } }; fIncludedByAction= new Action(IBMessages.IBViewPart_showIncludedBy_label, IAction.AS_RADIO_BUTTON) { - public void run() { + @Override + public void run() { if (isChecked()) { onSetDirection(true); } @@ -431,7 +439,8 @@ public class IBViewPart extends ViewPart fIncludesToAction= new Action(IBMessages.IBViewPart_showIncludesTo_label, IAction.AS_RADIO_BUTTON) { - public void run() { + @Override + public void run() { if (isChecked()) { onSetDirection(false); } @@ -441,7 +450,8 @@ public class IBViewPart extends ViewPart CPluginImages.setImageDescriptors(fIncludesToAction, CPluginImages.T_LCL, CPluginImages.IMG_ACTION_SHOW_RELATES_TO); fInactiveFilter= new ViewerFilter() { - public boolean select(Viewer viewer, Object parentElement, Object element) { + @Override + public boolean select(Viewer viewer, Object parentElement, Object element) { if (element instanceof IBNode) { IBNode node= (IBNode) element; return node.isActiveCode(); @@ -450,7 +460,8 @@ public class IBViewPart extends ViewPart } }; fFilterInactiveAction= new Action(IBMessages.IBViewPart_hideInactive_label, IAction.AS_CHECK_BOX) { - public void run() { + @Override + public void run() { if (isChecked()) { fTreeViewer.addFilter(fInactiveFilter); } @@ -463,7 +474,8 @@ public class IBViewPart extends ViewPart CPluginImages.setImageDescriptors(fFilterInactiveAction, CPluginImages.T_LCL, CPluginImages.IMG_ACTION_HIDE_INACTIVE); fSystemFilter= new ViewerFilter() { - public boolean select(Viewer viewer, Object parentElement, Object element) { + @Override + public boolean select(Viewer viewer, Object parentElement, Object element) { if (element instanceof IBNode) { IBNode node= (IBNode) element; return !node.isSystemInclude(); @@ -472,7 +484,8 @@ public class IBViewPart extends ViewPart } }; fFilterSystemAction= new Action(IBMessages.IBViewPart_hideSystem_label, IAction.AS_CHECK_BOX) { - public void run() { + @Override + public void run() { if (isChecked()) { fTreeViewer.addFilter(fSystemFilter); } @@ -486,13 +499,15 @@ public class IBViewPart extends ViewPart fSorterAlphaNumeric= new ViewerComparator(); fSorterReferencePosition= new ViewerComparator() { - public int category(Object element) { + @Override + public int category(Object element) { if (element instanceof IBNode) { return 0; } return 1; } - public int compare(Viewer viewer, Object e1, Object e2) { + @Override + public int compare(Viewer viewer, Object e1, Object e2) { if (!(e1 instanceof IBNode)) { if (!(e2 instanceof IBNode)) { return 0; @@ -509,13 +524,15 @@ public class IBViewPart extends ViewPart }; fShowFolderInLabelsAction= new Action(IBMessages.IBViewPart_showFolders_label, IAction.AS_CHECK_BOX) { - public void run() { + @Override + public void run() { onShowFolderInLabels(isChecked()); } }; fShowFolderInLabelsAction.setToolTipText(IBMessages.IBViewPart_showFolders_tooltip); fNextAction = new Action(IBMessages.IBViewPart_nextMatch_label) { - public void run() { + @Override + public void run() { onNextOrPrevious(true); } }; @@ -523,7 +540,8 @@ public class IBViewPart extends ViewPart CPluginImages.setImageDescriptors(fNextAction, CPluginImages.T_LCL, CPluginImages.IMG_SHOW_NEXT); fPreviousAction = new Action(IBMessages.IBViewPart_previousMatch_label) { - public void run() { + @Override + public void run() { onNextOrPrevious(false); } }; @@ -531,7 +549,8 @@ public class IBViewPart extends ViewPart CPluginImages.setImageDescriptors(fPreviousAction, CPluginImages.T_LCL, CPluginImages.IMG_SHOW_PREV); fRefreshAction = new Action(IBMessages.IBViewPart_refresh_label) { - public void run() { + @Override + public void run() { onRefresh(); } }; @@ -694,7 +713,8 @@ public class IBViewPart extends ViewPart // open include if (node.getParent() != null && node.getDirectiveFile() != null) { m.add(new Action(IBMessages.IBViewPart_showInclude_label) { - public void run() { + @Override + public void run() { onShowInclude(selection); } }); @@ -707,15 +727,6 @@ public class IBViewPart extends ViewPart ofa.selectionChanged(selection); m.add(ofa); - // open with - // keep the menu shorter, no open with support -// final IResource r= tu.getResource(); -// if (r != null) { -// IMenuManager submenu= new MenuManager(IBMessages.IBViewPart_OpenWithMenu_label); -// submenu.add(new OpenWithMenu(page, r)); -// m.add(submenu); -// } - // show in IMenuManager submenu= new MenuManager(IBMessages.IBViewPart_ShowInMenu_label); submenu.add(ContributionItemFactory.VIEWS_SHOW_IN.create(getSite().getWorkbenchWindow())); @@ -723,7 +734,8 @@ public class IBViewPart extends ViewPart if (node.getParent() != null) { m.add(new Separator()); m.add(new Action(Messages.format(IBMessages.IBViewPart_FocusOn_label, tu.getPath().lastSegment())) { - public void run() { + @Override + public void run() { setInput(tu); } }); @@ -804,7 +816,7 @@ public class IBViewPart extends ViewPart } public ITranslationUnit[] getHistoryEntries() { - return (ITranslationUnit[]) fHistoryEntries.toArray(new ITranslationUnit[fHistoryEntries.size()]); + return fHistoryEntries.toArray(new ITranslationUnit[fHistoryEntries.size()]); } public void setHistoryEntries(ITranslationUnit[] remaining) { diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/navigator/CNavigatorRefactorActionProvider.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/navigator/CNavigatorRefactorActionProvider.java index a19b01532cc..2a592570131 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/navigator/CNavigatorRefactorActionProvider.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/navigator/CNavigatorRefactorActionProvider.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2006, 2007 IBM Corporation and others. + * Copyright (c) 2006, 2008 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -23,7 +23,7 @@ import org.eclipse.ui.navigator.ICommonActionExtensionSite; import org.eclipse.ui.navigator.ICommonViewerWorkbenchSite; import org.eclipse.ui.operations.UndoRedoActionGroup; -import org.eclipse.cdt.refactoring.actions.CRefactoringActionGroup; +import org.eclipse.cdt.ui.refactoring.actions.CRefactoringActionGroup; import org.eclipse.cdt.internal.ui.actions.SelectionConverter; @@ -41,6 +41,7 @@ public class CNavigatorRefactorActionProvider extends CommonActionProvider { /* * @see org.eclipse.ui.navigator.CommonActionProvider#init(org.eclipse.ui.navigator.ICommonActionExtensionSite) */ + @Override public void init(ICommonActionExtensionSite actionSite) { site = actionSite; resourceRefactorGroup= new CNavigatorRefactorActionGroup(site.getViewSite().getShell(), (Tree)site.getStructuredViewer().getControl()); @@ -55,12 +56,14 @@ public class CNavigatorRefactorActionProvider extends CommonActionProvider { } } + @Override public void dispose() { undoRedoGroup.dispose(); resourceRefactorGroup.dispose(); cElementRefactorGroup.dispose(); } + @Override public void fillActionBars(IActionBars actionBars) { undoRedoGroup.fillActionBars(actionBars); resourceRefactorGroup.fillActionBars(actionBars); @@ -68,18 +71,21 @@ public class CNavigatorRefactorActionProvider extends CommonActionProvider { cElementRefactorGroup.fillActionBars(actionBars); } + @Override public void fillContextMenu(IMenuManager menu) { undoRedoGroup.fillContextMenu(menu); resourceRefactorGroup.fillContextMenu(menu); cElementRefactorGroup.fillContextMenu(menu); } + @Override public void setContext(ActionContext context) { undoRedoGroup.setContext(context); resourceRefactorGroup.setContext(convertToResources(context)); cElementRefactorGroup.setContext(context); } + @Override public void updateActionBars() { undoRedoGroup.updateActionBars(); resourceRefactorGroup.updateActionBars(); diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/AddDeclarationNodeToClassChange.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/AddDeclarationNodeToClassChange.java new file mode 100644 index 00000000000..ef51fa2fb48 --- /dev/null +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/AddDeclarationNodeToClassChange.java @@ -0,0 +1,133 @@ +/******************************************************************************* + * Copyright (c) 2007, 2008 Institute for Software, HSR Hochschule fuer Technik + * Rapperswil, University of applied sciences and others + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Institute for Software - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.ui.refactoring; + +import org.eclipse.osgi.util.NLS; +import org.eclipse.text.edits.TextEditGroup; + +import org.eclipse.cdt.core.dom.ast.IASTDeclaration; +import org.eclipse.cdt.core.dom.ast.IASTDeclarator; +import org.eclipse.cdt.core.dom.ast.IASTFunctionDeclarator; +import org.eclipse.cdt.core.dom.ast.IASTNode; +import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTVisiblityLabel; +import org.eclipse.cdt.core.dom.rewrite.ASTRewrite; + +import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTVisibilityLabel; + +import org.eclipse.cdt.internal.ui.refactoring.utils.VisibilityEnum; + +public class AddDeclarationNodeToClassChange { + + private final ICPPASTCompositeTypeSpecifier nodeClass; + private final VisibilityEnum visibility; + private final IASTNode fieldNodes; + private final ModificationCollector collector; + + public static void createChange(ICPPASTCompositeTypeSpecifier nodeClass, VisibilityEnum visibility, IASTNode fieldNodes, boolean isField, ModificationCollector collector) { + new AddDeclarationNodeToClassChange(nodeClass, visibility, fieldNodes, collector, isField); + } + + private AddDeclarationNodeToClassChange(ICPPASTCompositeTypeSpecifier nodeClass, VisibilityEnum visibility, IASTNode fieldNodes, ModificationCollector collector, boolean isField) { + this.nodeClass = nodeClass; + this.visibility = visibility; + this.fieldNodes = fieldNodes; + this.collector = collector; + createRewrites(isField); + } + + private void createRewrites(boolean isField) { + int lastFunctionDeclaration = -1; + int lastFieldDeclaration = -1; + IASTDeclaration[] members = nodeClass.getMembers(); + + // XXX Don't we have to differentiate between the default visibility in a class and a struct? + VisibilityEnum currentVisibility = VisibilityEnum.v_private; + + // Find the insert location by iterating over the elements of the class + // and remembering the last element with the matching visibility + for(int i = 0; i < members.length; i++) { + IASTDeclaration declaration = members[i]; + + if(declaration instanceof ICPPASTVisiblityLabel){ + currentVisibility = VisibilityEnum.from((ICPPASTVisiblityLabel) declaration); + } + + if (declaration instanceof IASTSimpleDeclaration) { + IASTSimpleDeclaration simple = (IASTSimpleDeclaration) declaration; + IASTDeclarator[] declarators = simple.getDeclarators(); + if(declarators.length > 0 && declarators[0] != null && declarators[0] instanceof IASTFunctionDeclarator){ + if(currentVisibility.equals(visibility)){ + lastFunctionDeclaration = i; + } + + } else if (declarators.length > 0 && declarators[0] != null){ + if(currentVisibility.equals(visibility)){ + lastFieldDeclaration = i; + } + } + } + } + + IASTDeclaration nextFunctionDeclaration = null; + if (lastFunctionDeclaration < members.length-1 && lastFunctionDeclaration >= 0) + nextFunctionDeclaration = members[lastFunctionDeclaration+1]; + + IASTDeclaration nextFieldDeclaration = null; + if (lastFieldDeclaration < members.length-1 && lastFieldDeclaration >= 0) + nextFieldDeclaration = members[lastFieldDeclaration +1]; + + createInsert(isField, nextFunctionDeclaration, nextFieldDeclaration, currentVisibility); + } + + private void createInsert(boolean isField, IASTDeclaration nextFunctionDeclaration, IASTDeclaration nextFieldDeclaration, VisibilityEnum currentVisibility) { + if(isField) { + if(nextFieldDeclaration != null) { + insertBefore(nextFieldDeclaration); + } else if(nextFunctionDeclaration != null){ + insertBefore(nextFunctionDeclaration); + } else { + insertAtTheEnd(currentVisibility); + } + } else { + if(nextFunctionDeclaration != null){ + insertBefore(nextFunctionDeclaration); + } else if(nextFieldDeclaration != null) { + insertBefore(nextFieldDeclaration); + } else { + insertAtTheEnd(currentVisibility); + } + } + } + + private void insertBefore(IASTNode nearestNode) { + ASTRewrite rewrite = collector.rewriterForTranslationUnit(nearestNode.getTranslationUnit()); + rewrite.insertBefore(nearestNode.getParent(), nearestNode, fieldNodes, createEditDescription()); + } + + private void insertAtTheEnd(VisibilityEnum currentVisibility) { + + ASTRewrite rewrite = collector.rewriterForTranslationUnit(nodeClass.getTranslationUnit()); + + if(! currentVisibility.equals(visibility)) { + ICPPASTVisiblityLabel label = new CPPASTVisibilityLabel(visibility.getICPPASTVisiblityLabelVisibility()); + rewrite.insertBefore(nodeClass, null, label, createEditDescription()); + } + + rewrite.insertBefore(nodeClass, null, fieldNodes, createEditDescription()); + } + + private TextEditGroup createEditDescription() { + return new TextEditGroup(NLS.bind(Messages.AddDeclarationNodeToClassChange_AddDeclaration, nodeClass.getName())); + } +} diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/CRefactoring.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/CRefactoring.java new file mode 100644 index 00000000000..d7142ccf237 --- /dev/null +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/CRefactoring.java @@ -0,0 +1,425 @@ +/******************************************************************************* + * Copyright (c) 2008 Institute for Software, HSR Hochschule fuer Technik + * Rapperswil, University of applied sciences and others + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Institute for Software - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.ui.refactoring; + +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.ResourcesPlugin; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.OperationCanceledException; +import org.eclipse.core.runtime.Path; +import org.eclipse.core.runtime.SubMonitor; +import org.eclipse.jface.text.ITextSelection; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.ltk.core.refactoring.Change; +import org.eclipse.ltk.core.refactoring.Refactoring; +import org.eclipse.ltk.core.refactoring.RefactoringStatus; +import org.eclipse.ui.IWorkbenchPage; + +import org.eclipse.cdt.core.CCorePlugin; +import org.eclipse.cdt.core.dom.ast.ASTVisitor; +import org.eclipse.cdt.core.dom.ast.IASTDeclaration; +import org.eclipse.cdt.core.dom.ast.IASTExpression; +import org.eclipse.cdt.core.dom.ast.IASTFileLocation; +import org.eclipse.cdt.core.dom.ast.IASTFunctionDeclarator; +import org.eclipse.cdt.core.dom.ast.IASTFunctionDefinition; +import org.eclipse.cdt.core.dom.ast.IASTMacroExpansionLocation; +import org.eclipse.cdt.core.dom.ast.IASTName; +import org.eclipse.cdt.core.dom.ast.IASTNode; +import org.eclipse.cdt.core.dom.ast.IASTNodeLocation; +import org.eclipse.cdt.core.dom.ast.IASTProblem; +import org.eclipse.cdt.core.dom.ast.IASTProblemDeclaration; +import org.eclipse.cdt.core.dom.ast.IASTProblemExpression; +import org.eclipse.cdt.core.dom.ast.IASTProblemStatement; +import org.eclipse.cdt.core.dom.ast.IASTProblemTypeId; +import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration; +import org.eclipse.cdt.core.dom.ast.IASTStatement; +import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit; +import org.eclipse.cdt.core.dom.ast.IASTTypeId; +import org.eclipse.cdt.core.dom.ast.IBinding; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTQualifiedName; +import org.eclipse.cdt.core.index.IIndex; +import org.eclipse.cdt.core.model.CoreModel; +import org.eclipse.cdt.core.model.ICProject; +import org.eclipse.cdt.core.model.ITranslationUnit; + +import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguousDeclaration; +import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguousExpression; +import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguousStatement; +import org.eclipse.cdt.internal.core.dom.parser.IASTDeclarationAmbiguity; + +import org.eclipse.cdt.internal.ui.refactoring.utils.EclipseObjects; + +public abstract class CRefactoring extends Refactoring { + protected static final String EMPTY_STRING = ""; //$NON-NLS-1$ + private static final int AST_STYLE = ITranslationUnit.AST_CONFIGURE_USING_SOURCE_CONTEXT | ITranslationUnit.AST_SKIP_INDEXED_HEADERS; + + protected String name = Messages.HSRRefactoring_name; + protected IFile file; + protected ISelection selection; + protected RefactoringStatus initStatus; + protected IASTTranslationUnit unit; + private IIndex fIndex; + public static final String NEWLINE = System.getProperty("line.separator"); //$NON-NLS-1$ + + public CRefactoring(IFile file, ISelection selection, boolean runHeadless) { + this.file = file; + this.selection = selection; + this.initStatus=new RefactoringStatus(); + + if(!runHeadless) { + IWorkbenchPage activePage = EclipseObjects.getActivePage(); + + if(!activePage.saveAllEditors(true)){ + initStatus.addError("EDITOR_NOT_SAVE"); //$NON-NLS-1$ + } + } + if(selection == null){ + initStatus.addError(Messages.HSRRefactoring_SelectionNotValid); + } + + } + + public CRefactoring(IFile file, ISelection selection) { + this(file, selection, false); + } + + private class ProblemFinder extends ASTVisitor{ + + private boolean problemFound = false; + private final RefactoringStatus status; + + public ProblemFinder(RefactoringStatus status){ + this.status = status; + } + + { + shouldVisitProblems = true; + shouldVisitDeclarations = true; + shouldVisitExpressions = true; + shouldVisitStatements = true; + shouldVisitTypeIds = true; + } + + @Override + public int visit(IASTProblem problem) { + addWarningToState(); + return ASTVisitor.PROCESS_CONTINUE; + } + + @Override + public int visit(IASTDeclaration declaration) { + if (declaration instanceof IASTProblemDeclaration) { + addWarningToState(); + } + return ASTVisitor.PROCESS_CONTINUE; + } + + @Override + public int visit(IASTExpression expression) { + if (expression instanceof IASTProblemExpression) { + addWarningToState(); + } + return ASTVisitor.PROCESS_CONTINUE; + } + + @Override + public int visit(IASTStatement statement) { + if (statement instanceof IASTProblemStatement) { + addWarningToState(); + } + return ASTVisitor.PROCESS_CONTINUE; + } + + @Override + public int visit(IASTTypeId typeId) { + if (typeId instanceof IASTProblemTypeId) { + addWarningToState(); + } + return ASTVisitor.PROCESS_CONTINUE; + } + + public boolean hasProblem() { + return problemFound; + } + + private void addWarningToState() { + if(!problemFound){ + status.addWarning(Messages.HSRRefactoring_CompileErrorInTU); + problemFound = true; + } + } + + } + + private class AmbiguityFinder extends ASTVisitor{ + + private boolean ambiguityFound = false; + + { + shouldVisitDeclarations = true; + shouldVisitExpressions = true; + shouldVisitStatements= true; + } + + @Override + public int visit(IASTDeclaration declaration) { + if (declaration instanceof IASTAmbiguousDeclaration || declaration instanceof IASTDeclarationAmbiguity) { + ambiguityFound = true; + } + return ASTVisitor.PROCESS_CONTINUE; + } + + @Override + public int visit(IASTExpression expression) { + if (expression instanceof IASTAmbiguousExpression) { + ambiguityFound = true; + } + return ASTVisitor.PROCESS_CONTINUE; + } + + @Override + public int visit(IASTStatement statement) { + if (statement instanceof IASTAmbiguousStatement) { + ambiguityFound = true; + } + return ASTVisitor.PROCESS_CONTINUE; + } + + public boolean ambiguityFound() { + return ambiguityFound; + } + + } + + @Override + public RefactoringStatus checkFinalConditions(IProgressMonitor pm) + throws CoreException, OperationCanceledException { + RefactoringStatus status = new RefactoringStatus(); + return status; + } + + @Override + public RefactoringStatus checkInitialConditions(IProgressMonitor pm) + throws CoreException, OperationCanceledException { + SubMonitor sm = SubMonitor.convert(pm, 10); + sm.subTask(Messages.HSRRefactoring_PM_LoadTU); + if(isProgressMonitorCanceld(sm, initStatus)) { + return initStatus; + } + if(!loadTranslationUnit(initStatus, sm.newChild(8))){ + initStatus.addError(Messages.HSRRefactoring_CantLoadTU); + } + if(isProgressMonitorCanceld(sm, initStatus)) { + return initStatus; + } + sm.subTask(Messages.HSRRefactoring_PM_CheckTU); + translationUnitHasProblem(); + if(translationUnitIsAmbiguous()) { + initStatus.addError(Messages.HSRRefactoring_Ambiguity); + } + sm.worked(2); + sm.subTask(Messages.HSRRefactoring_PM_InitRef); + sm.done(); + return initStatus; + } + + protected boolean isProgressMonitorCanceld(IProgressMonitor sm, + RefactoringStatus initStatus2) { + if(sm.isCanceled()) { + initStatus2.addFatalError(Messages.HSRRefactoring_CanceledByUser); + return true; + } + return false; + } + + @Override + public Change createChange(IProgressMonitor pm) throws CoreException, OperationCanceledException { + ModificationCollector collector = new ModificationCollector(); + collectModifications(pm, collector); + return collector.createFinalChange(); + } + + protected void collectModifications(IProgressMonitor pm, ModificationCollector collector) + throws CoreException, OperationCanceledException { + } + + @Override + public String getName() { + return name; + } + + protected boolean loadTranslationUnit(RefactoringStatus status, IProgressMonitor mon) { + SubMonitor subMonitor = SubMonitor.convert(mon, 10); + if (file != null) { + try { + subMonitor.subTask(Messages.HSRRefactoring_PM_ParseTU); + ITranslationUnit tu = (ITranslationUnit) CCorePlugin + .getDefault().getCoreModel().create(file); + unit = tu.getAST(fIndex, AST_STYLE); + subMonitor.worked(2); + if(isProgressMonitorCanceld(subMonitor, initStatus)) { + return true; + } + subMonitor.subTask(Messages.HSRRefactoring_PM_MergeComments); + + subMonitor.worked(8); + } catch (CoreException e) { + status.addFatalError(e.getMessage()); + subMonitor.done(); + return false; + } + + } else { + status.addFatalError(Messages.NO_FILE); + subMonitor.done(); + return false; + } + subMonitor.done(); + return true; + } + + private static class ExpressionPosition { + public int start; + public int end; + + @Override + public String toString() { + return String.format("Position ranges from %d to %d and has a length of %d", Integer.valueOf(start), //$NON-NLS-1$ + Integer.valueOf(end), Integer.valueOf(end - start)); + } + } + + protected static ExpressionPosition createExpressionPosition(IASTNode expression) { + ExpressionPosition selection = new ExpressionPosition(); + + int nodeLength = 0; + IASTNodeLocation[] nodeLocations = expression.getNodeLocations(); + if (nodeLocations.length != 1) { + for (IASTNodeLocation location : nodeLocations) { + if (location instanceof IASTMacroExpansionLocation) { + IASTMacroExpansionLocation macroLoc = (IASTMacroExpansionLocation) location; + selection.start = macroLoc.asFileLocation().getNodeOffset(); + nodeLength = macroLoc.asFileLocation().getNodeLength(); + } + } + } else { + if (nodeLocations[0] instanceof IASTMacroExpansionLocation) { + IASTMacroExpansionLocation macroLoc = (IASTMacroExpansionLocation) nodeLocations[0]; + selection.start = macroLoc.asFileLocation().getNodeOffset(); + nodeLength = macroLoc.asFileLocation().getNodeLength(); + } else { + IASTFileLocation loc = expression.getFileLocation(); + selection.start = loc.getNodeOffset(); + nodeLength = loc.getNodeLength(); + } + } + selection.end = selection.start + nodeLength; + return selection; + } + + protected boolean isExpressionWhollyInSelection(ITextSelection textSelection, IASTNode expression) { + ExpressionPosition exprPos = createExpressionPosition(expression); + + int selStart = textSelection.getOffset(); + int selEnd = textSelection.getLength() + selStart; + + return exprPos.start >= selStart && exprPos.end <= selEnd; + } + + public static boolean isSelectionOnExpression(ITextSelection textSelection, IASTNode expression) { + ExpressionPosition exprPos = createExpressionPosition(expression); + int selStart = textSelection.getOffset(); + int selEnd = textSelection.getLength() + selStart; + return exprPos.end > selStart && exprPos.start < selEnd; + } + + protected boolean isInSameFile(IASTNode node) { + IPath path = new Path(node.getContainingFilename()); + IFile locFile = ResourcesPlugin.getWorkspace().getRoot().getFile(file.getLocation()); + IFile tmpFile = ResourcesPlugin.getWorkspace().getRoot().getFile(path); + return locFile.equals(tmpFile); + } + + protected boolean isInSameFileSelection(ITextSelection textSelection, IASTNode node) { + if( isInSameFile(node) ) { + return isSelectionOnExpression(textSelection, node); + } + return false; + } + + protected MethodContext findContext(IASTNode node) { + boolean found = false; + MethodContext context = new MethodContext(); + context.setType(MethodContext.ContextType.NONE); + IASTName name = null; + while(node != null && !found){ + node = node.getParent(); + if(node instanceof IASTFunctionDeclarator){ + name=((IASTFunctionDeclarator)node).getName(); + found = true; + context.setType(MethodContext.ContextType.FUNCTION); + } else if (node instanceof IASTFunctionDefinition){ + name=((IASTFunctionDefinition)node).getDeclarator().getName(); + found = true; + context.setType(MethodContext.ContextType.FUNCTION); + } + } + if(name instanceof ICPPASTQualifiedName){ + ICPPASTQualifiedName qname =( ICPPASTQualifiedName )name; + context.setMethodQName(qname); + IBinding bind = qname.resolveBinding(); + IASTName[] decl = unit.getDeclarationsInAST(bind);//TODO HSR funktioniert nur fuer namen aus der aktuellen Translationunit + for (IASTName tmpname : decl) { + IASTNode methoddefinition = tmpname.getParent().getParent(); + if (methoddefinition instanceof IASTSimpleDeclaration) { + context.setMethodDeclarationName(tmpname); + context.setType(MethodContext.ContextType.METHOD); + } + } + + } + return context; + } + + protected boolean translationUnitHasProblem() { + ProblemFinder pf = new ProblemFinder(initStatus); + unit.accept(pf); + return pf.hasProblem(); + } + + protected boolean translationUnitIsAmbiguous() { + AmbiguityFinder af = new AmbiguityFinder(); + unit.accept(af); + return af.ambiguityFound(); + } + + public void lockIndex() throws CoreException, InterruptedException { + if (fIndex == null) { + ICProject[] projects= CoreModel.getDefault().getCModel().getCProjects(); + fIndex= CCorePlugin.getIndexManager().getIndex(projects); + } + fIndex.acquireReadLock(); + } + + public void unlockIndex() { + if (fIndex != null) { + fIndex.releaseReadLock(); + } + fIndex= null; + } + + public IIndex getIndex() { + return fIndex; + } +} diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/CTextFileChangeFactory.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/CTextFileChangeFactory.java new file mode 100644 index 00000000000..41868e1e6f6 --- /dev/null +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/CTextFileChangeFactory.java @@ -0,0 +1,29 @@ +/******************************************************************************* + * Copyright (c) 2008 Wind River Systems, Inc. and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Markus Schorn - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.ui.refactoring; + +import org.eclipse.core.resources.IFile; +import org.eclipse.ltk.core.refactoring.TextFileChange; + +import org.eclipse.cdt.ui.refactoring.CTextFileChange; + +import org.eclipse.cdt.internal.core.dom.rewrite.ICTextFileChangeFactory; + +/** + * Factory provided to the core plugin to create appropriate text file changes. + * @since 5.0 + */ +public class CTextFileChangeFactory implements ICTextFileChangeFactory { + + public TextFileChange createCTextFileChange(IFile file) { + return new CTextFileChange(file.getName(), file); + } +} diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/Container.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/Container.java new file mode 100644 index 00000000000..af997d4c74e --- /dev/null +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/Container.java @@ -0,0 +1,34 @@ +/******************************************************************************* + * Copyright (c) 2008 Institute for Software, HSR Hochschule fuer Technik + * Rapperswil, University of applied sciences and others + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Institute for Software - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.ui.refactoring; + +public class Container{ + private T object; + + public Container(T object) { + super(); + this.object = object; + } + + public Container() { + super(); + this.object = null; + } + + public T getObject() { + return object; + } + + public void setObject(T object) { + this.object = object; + } +} diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/CreateFileChange.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/CreateFileChange.java new file mode 100644 index 00000000000..8706ff46464 --- /dev/null +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/CreateFileChange.java @@ -0,0 +1,119 @@ +/******************************************************************************* + * Copyright (c) 2008 Institute for Software, HSR Hochschule fuer Technik + * Rapperswil, University of applied sciences and others + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Institute for Software - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.ui.refactoring; + +import java.io.ByteArrayInputStream; +import java.io.InputStream; +import java.net.URI; + +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.ResourcesPlugin; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.OperationCanceledException; +import org.eclipse.core.runtime.SubProgressMonitor; +import org.eclipse.ltk.core.refactoring.Change; +import org.eclipse.ltk.core.refactoring.RefactoringStatus; +import org.eclipse.osgi.util.NLS; + +/** + * @author Emanuel Graf + * + */ +public class CreateFileChange extends Change { + + private String name; + private final IPath path; + private final String source; + private final String encoding; + + + + public CreateFileChange(String name, IPath path, String source, String encoding) { + super(); + this.name = name; + this.path = path; + this.source = source; + this.encoding = encoding; + } + + public CreateFileChange(IPath path, String source, String encoding) { + this(null, path, source, encoding); + } + + @Override + public Object getModifiedElement() { + IFile file = ResourcesPlugin.getWorkspace().getRoot().getFile(path); + return file; + } + + @Override + public String getName() { + if(name == null) { + return NLS.bind(Messages.CreateFileChange_CreateFile, path.toOSString()); + }else { + return name; + } + } + + @Override + public void initializeValidationData(IProgressMonitor pm) { + } + + @Override + public RefactoringStatus isValid(IProgressMonitor pm) throws CoreException, + OperationCanceledException { + RefactoringStatus result= new RefactoringStatus(); + IFile file= ResourcesPlugin.getWorkspace().getRoot().getFile(path); + + URI location= file.getLocationURI(); + if (location == null) { + result.addFatalError(NLS.bind(Messages.CreateFileChange_UnknownLoc, file.getFullPath().toString())); + return result; + } + + if (file.exists()) { + result.addFatalError( NLS.bind(Messages.CreateFileChange_FileExists, + file.getFullPath().toString())); + return result; + } + return result; + } + + @Override + public Change perform(IProgressMonitor pm) throws CoreException { + IFile file= ResourcesPlugin.getWorkspace().getRoot().getFile(path); + InputStream is = new ByteArrayInputStream(source.getBytes()); + file.create(is, false, new SubProgressMonitor(pm, 1)); + if(encoding != null) { + file.setCharset(encoding, new SubProgressMonitor(pm,1)); + } + return new DeleteFileChange(file.getFullPath()); + } + + + + public String getSource() { + return source; + } + + public void setName(String name) { + this.name = name; + } + + @Override + public String toString() { + return getName(); + } + +} diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/DeleteFileChange.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/DeleteFileChange.java new file mode 100644 index 00000000000..911efce1422 --- /dev/null +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/DeleteFileChange.java @@ -0,0 +1,105 @@ +/******************************************************************************* + * Copyright (c) 2008 Institute for Software, HSR Hochschule fuer Technik + * Rapperswil, University of applied sciences and others + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Institute for Software - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.ui.refactoring; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; + +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.ResourcesPlugin; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.OperationCanceledException; +import org.eclipse.ltk.core.refactoring.Change; +import org.eclipse.ltk.core.refactoring.RefactoringStatus; + +/** + * @author Emanuel Graf + * + */ +public class DeleteFileChange extends Change { + + private IPath path; + private String source; + + public DeleteFileChange(IPath path) { + this.path = path; + } + + @Override + public Object getModifiedElement() { + return path; + } + + + @Override + public String getName() { + return Messages.DeleteFileChange_0 + path.toOSString(); + } + + + @Override + public void initializeValidationData(IProgressMonitor pm) { + // Nothing to do + } + + @Override + public RefactoringStatus isValid(IProgressMonitor pm) throws CoreException, + OperationCanceledException { + RefactoringStatus status = new RefactoringStatus(); + IFile file = ResourcesPlugin.getWorkspace().getRoot().getFile(path); + if(!file.exists()) { + status.addFatalError(Messages.DeleteFileChange_1 + path.toString()); + } + return status; + } + + private String getSource(IFile file) throws CoreException { + String encoding= null; + try { + encoding= file.getCharset(); + } catch (CoreException ex) { + // fall through. Take default encoding. + } + StringBuffer sb= new StringBuffer(); + BufferedReader br= null; + InputStream in= null; + try { + in= file.getContents(); + if (encoding != null) + br= new BufferedReader(new InputStreamReader(in, encoding)); + else + br= new BufferedReader(new InputStreamReader(in)); + int read= 0; + while ((read= br.read()) != -1) { + sb.append((char) read); + } + br.close(); + } catch (IOException e){ + + } + return sb.toString(); + } + + @Override + public Change perform(IProgressMonitor pm) throws CoreException { + IFile file= ResourcesPlugin.getWorkspace().getRoot().getFile(path); + source = getSource(file); + Change undo = new CreateFileChange(file.getFullPath(), source, file.getCharset()); + file.delete(true,true, pm); + return undo; + } + +} diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/DocumentAdapter.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/DocumentAdapter.java new file mode 100644 index 00000000000..03edd5320b0 --- /dev/null +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/DocumentAdapter.java @@ -0,0 +1,493 @@ +/******************************************************************************* + * Copyright (c) 2002, 2007 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Rational Software - Initial API and implementation + * Markus Schorn (Wind River Systems) + *******************************************************************************/ +package org.eclipse.cdt.internal.ui.refactoring; + + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Set; + +import org.eclipse.core.filebuffers.FileBuffers; +import org.eclipse.core.filebuffers.ITextFileBuffer; +import org.eclipse.core.filebuffers.ITextFileBufferManager; +import org.eclipse.core.filebuffers.LocationKind; +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.resources.ResourceAttributes; +import org.eclipse.core.runtime.Assert; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IAdaptable; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.NullProgressMonitor; +import org.eclipse.jface.text.BadLocationException; +import org.eclipse.jface.text.DefaultLineTracker; +import org.eclipse.jface.text.DocumentEvent; +import org.eclipse.jface.text.IDocument; +import org.eclipse.jface.text.IDocumentListener; +import org.eclipse.swt.widgets.Display; + +import org.eclipse.cdt.core.CCorePlugin; +import org.eclipse.cdt.core.model.BufferChangedEvent; +import org.eclipse.cdt.core.model.CModelException; +import org.eclipse.cdt.core.model.IBuffer; +import org.eclipse.cdt.core.model.IBufferChangedListener; +import org.eclipse.cdt.core.model.IOpenable; +import org.eclipse.cdt.core.model.ITranslationUnit; +import org.eclipse.cdt.core.model.IWorkingCopy; + +import org.eclipse.cdt.internal.core.model.IBufferFactory; + + +/** + * Adapts IDocument to IBuffer. Uses the + * same algorithm as the text widget to determine the buffer's line delimiter. + * All text inserted into the buffer is converted to this line delimiter. + * This class is public for test purposes only. + * + * This class is similar to the JDT DocumentAdapter class. + */ +public class DocumentAdapter implements IBuffer, IAdaptable, IDocumentListener { + + /** + * Executes a document set content call in the ui thread. + */ + protected class DocumentSetCommand implements Runnable { + + private String fContents; + + public void run() { + fDocument.set(fContents); + } + + public void set(String contents) { + fContents= contents; + Display.getDefault().syncExec(this); + } + } + + /** + * Executes a document replace call in the ui thread. + */ + protected class DocumentReplaceCommand implements Runnable { + + private int fOffset; + private int fLength; + private String fText; + + public void run() { + try { + fDocument.replace(fOffset, fLength, fText); + } catch (BadLocationException x) { + // ignore + } + } + + public void replace(int offset, int length, String text) { + fOffset= offset; + fLength= length; + fText= text; + Display.getDefault().syncExec(this); + } + } + + private static final boolean DEBUG_LINE_DELIMITERS= true; + public static final IBuffer NULL_BUFFER = new IBuffer(){ + public void addBufferChangedListener(IBufferChangedListener listener) {} + public void append(char[] text) {} + public void append(String text) {} + public void close() {} + public char getChar(int position) {return 0;} + public char[] getCharacters() {return new char[0];} + public String getContents() {return "";} //$NON-NLS-1$ + public int getLength() {return 0;} + public IOpenable getOwner() {return null;} + public String getText(int offset, int length) {return "";} //$NON-NLS-1$ + public IResource getUnderlyingResource() {return null;} + public boolean hasUnsavedChanges() {return false;} + public boolean isClosed() {return false;} + public boolean isReadOnly() {return true;} + public void removeBufferChangedListener(IBufferChangedListener listener) {} + public void replace(int position, int length, char[] text) {} + public void replace(int position, int length, String text) {} + public void save(IProgressMonitor progress, boolean force) throws CModelException {} + public void setContents(char[] contents) {} + public void setContents(String contents) {} + }; + + public static IBufferFactory FACTORY= new IBufferFactory() { + public IBuffer createBuffer(IOpenable owner) { + if (owner instanceof IWorkingCopy) { + IWorkingCopy wc= (IWorkingCopy) owner; + ITranslationUnit tu= wc.getOriginalElement(); + if (tu != null) { + IResource r= tu.getResource(); + if (r instanceof IFile) { + return new DocumentAdapter(wc, (IFile) r); + } + } + } + assert false; + return DocumentAdapter.NULL_BUFFER; + } + }; + + private ITranslationUnit fTranslationUnit; + private IWorkingCopy fOwner; + private IFile fFile; + private ITextFileBuffer fTextFileBuffer; + IDocument fDocument; + + private DocumentSetCommand fSetCmd= new DocumentSetCommand(); + private DocumentReplaceCommand fReplaceCmd= new DocumentReplaceCommand(); + + private Set fLegalLineDelimiters; + + private List fBufferListeners= new ArrayList(3); + private IStatus fStatus; + + + public DocumentAdapter(IWorkingCopy owner, IFile file) { + fOwner= owner; + fFile= file; + fTranslationUnit= owner.getOriginalElement(); + if (fTranslationUnit != null) { + addBufferChangedListener(fTranslationUnit); + } + initialize(); + } + + private void initialize() { + ITextFileBufferManager manager= FileBuffers.getTextFileBufferManager(); + IPath location= fFile.getFullPath(); + try { + manager.connect(location, LocationKind.IFILE, new NullProgressMonitor()); + fTextFileBuffer= manager.getTextFileBuffer(location, LocationKind.IFILE); + fDocument= fTextFileBuffer.getDocument(); + } catch (CoreException x) { + fStatus= x.getStatus(); + fDocument= manager.createEmptyDocument(location, LocationKind.IFILE); + } + fDocument.addPrenotifiedDocumentListener(this); + } + + /** + * Returns the status of this document adapter. + */ + public IStatus getStatus() { + if (fStatus != null) + return fStatus; + if (fTextFileBuffer != null) + return fTextFileBuffer.getStatus(); + return null; + } + + /** + * Returns the adapted document. + * + * @return the adapted document + */ + public IDocument getDocument() { + return fDocument; + } + + /* + * @see IBuffer#addBufferChangedListener(IBufferChangedListener) + */ + public void addBufferChangedListener(IBufferChangedListener listener) { + Assert.isNotNull(listener); + if (!fBufferListeners.contains(listener)) + fBufferListeners.add(listener); + } + + /* + * @see IBuffer#removeBufferChangedListener(IBufferChangedListener) + */ + public void removeBufferChangedListener(IBufferChangedListener listener) { + Assert.isNotNull(listener); + fBufferListeners.remove(listener); + } + + + /** + * @see org.eclipse.cdt.core.model.IBuffer#append(char[]) + */ + public void append(char[] text) { + append(new String(text)); + } + + /** + * @see org.eclipse.cdt.core.model.IBuffer#append(java.lang.String) + */ + public void append(String text) { + if (DEBUG_LINE_DELIMITERS) { + validateLineDelimiters(text); + } + fReplaceCmd.replace(fDocument.getLength(), 0, text); + } + + + /** + * @see org.eclipse.cdt.core.model.IBuffer#close() + */ + public void close() { + + if (isClosed()) + return; + + IDocument d= fDocument; + fDocument= null; + d.removePrenotifiedDocumentListener(this); + + if (fTextFileBuffer != null) { + ITextFileBufferManager manager= FileBuffers.getTextFileBufferManager(); + try { + manager.disconnect(fTextFileBuffer.getLocation(), LocationKind.IFILE, new NullProgressMonitor()); + } catch (CoreException x) { + // ignore + } + fTextFileBuffer= null; + } + + fireBufferChanged(new BufferChangedEvent(this, 0, 0, null)); + fBufferListeners.clear(); + } + + /** + * @see org.eclipse.cdt.core.model.IBuffer#getChar(int) + */ + public char getChar(int position) { + try { + return fDocument.getChar(position); + } catch (BadLocationException x) { + throw new ArrayIndexOutOfBoundsException(); + } + } + + /** + * @see org.eclipse.cdt.core.model.IBuffer#getCharacters() + */ + public char[] getCharacters() { + String content= getContents(); + return content == null ? null : content.toCharArray(); + } + + /** + * @see org.eclipse.cdt.core.model.IBuffer#getContents() + */ + public String getContents() { + return fDocument.get(); + } + + /** + * @see org.eclipse.cdt.core.model.IBuffer#getLength() + */ + public int getLength() { + return fDocument.getLength(); + } + + /** + * @see org.eclipse.cdt.core.model.IBuffer#getOwner() + */ + public IOpenable getOwner() { + return fOwner; + } + + /** + * @see org.eclipse.cdt.core.model.IBuffer#getText(int, int) + */ + public String getText(int offset, int length) { + try { + return fDocument.get(offset, length); + } catch (BadLocationException x) { + throw new ArrayIndexOutOfBoundsException(); + } + } + + /** + * @see org.eclipse.cdt.core.model.IBuffer#getUnderlyingResource() + */ + public IResource getUnderlyingResource() { + return fFile; + } + + /** + * @see org.eclipse.cdt.core.model.IBuffer#hasUnsavedChanges() + */ + public boolean hasUnsavedChanges() { + return fTextFileBuffer != null ? fTextFileBuffer.isDirty() : false; + } + + /** + * @see org.eclipse.cdt.core.model.IBuffer#isClosed() + */ + public boolean isClosed() { + return fDocument == null; + } + + /** + * @see org.eclipse.cdt.core.model.IBuffer#isReadOnly() + */ + public boolean isReadOnly() { + IResource resource= getUnderlyingResource(); + if (resource != null) { + ResourceAttributes attributes = resource.getResourceAttributes(); + if (attributes != null) { + return attributes.isReadOnly(); + } + } + return false; + } + + /** + * @see org.eclipse.cdt.core.model.IBuffer#replace(int, int, char[]) + */ + public void replace(int position, int length, char[] text) { + replace(position, length, new String(text)); + } + + /** + * @see org.eclipse.cdt.core.model.IBuffer#replace(int, int, java.lang.String) + */ + public void replace(int position, int length, String text) { + if (DEBUG_LINE_DELIMITERS) { + validateLineDelimiters(text); + } + fReplaceCmd.replace(position, length, text); + } + + /** + * @see org.eclipse.cdt.core.model.IBuffer#save(org.eclipse.core.runtime.IProgressMonitor, boolean) + */ + public void save(IProgressMonitor progress, boolean force) throws CModelException { + try { + if (fTextFileBuffer != null) + fTextFileBuffer.commit(progress, force); + } catch (CoreException e) { + throw new CModelException(e); + } + } + + /** + * @see org.eclipse.cdt.core.model.IBuffer#setContents(char[]) + */ + public void setContents(char[] contents) { + setContents(new String(contents)); + } + + /** + * @see org.eclipse.cdt.core.model.IBuffer#setContents(java.lang.String) + */ + public void setContents(String contents) { + int oldLength= fDocument.getLength(); + + if (contents == null) { + + if (oldLength != 0) + fSetCmd.set(""); //$NON-NLS-1$ + + } else { + // set only if different + if (DEBUG_LINE_DELIMITERS) { + validateLineDelimiters(contents); + } + + int newLength= contents.length(); + if (oldLength != newLength || !contents.equals(fDocument.get())) + fSetCmd.set(contents); + + } + } + + private void validateLineDelimiters(String contents) { + + if (fLegalLineDelimiters == null) { + // collect all line delimiters in the document + HashSet existingDelimiters= new HashSet(); + + for (int i= fDocument.getNumberOfLines() - 1; i >= 0; i-- ) { + try { + String curr= fDocument.getLineDelimiter(i); + if (curr != null) { + existingDelimiters.add(curr); + } + } catch (BadLocationException e) { + CCorePlugin.log(e); + } + } + if (existingDelimiters.isEmpty()) { + return; // first insertion of a line delimiter: no test + } + fLegalLineDelimiters= existingDelimiters; + + } + + DefaultLineTracker tracker= new DefaultLineTracker(); + tracker.set(contents); + + int lines= tracker.getNumberOfLines(); + if (lines <= 1) + return; + + for (int i= 0; i < lines; i++) { + try { + String curr= tracker.getLineDelimiter(i); + if (curr != null && !fLegalLineDelimiters.contains(curr)) { + StringBuffer buf= new StringBuffer("New line delimiter added to new code: "); //$NON-NLS-1$ + for (int k= 0; k < curr.length(); k++) { + buf.append(String.valueOf((int) curr.charAt(k))); + } + CCorePlugin.log(new Exception(buf.toString())); + } + } catch (BadLocationException e) { + CCorePlugin.log(e); + } + } + } + + /* + * @see IDocumentListener#documentAboutToBeChanged(DocumentEvent) + */ + public void documentAboutToBeChanged(DocumentEvent event) { + // there is nothing to do here + } + + /* + * @see IDocumentListener#documentChanged(DocumentEvent) + */ + public void documentChanged(DocumentEvent event) { + fireBufferChanged(new BufferChangedEvent(this, event.getOffset(), event.getLength(), event.getText())); + } + + private void fireBufferChanged(BufferChangedEvent event) { + if (fBufferListeners != null && fBufferListeners.size() > 0) { + Iterator e= new ArrayList(fBufferListeners).iterator(); + while (e.hasNext()) + e.next().bufferChanged(event); + } + } + + public ITextFileBuffer getTextFileBuffer() { + return fTextFileBuffer; + } + + @SuppressWarnings("unchecked") + public Object getAdapter(Class adapter) { + if (adapter.isAssignableFrom(ITextFileBuffer.class)) { + return fTextFileBuffer; + } + return null; + } +} diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/Messages.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/Messages.java new file mode 100644 index 00000000000..87eaa0e3483 --- /dev/null +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/Messages.java @@ -0,0 +1,46 @@ +/******************************************************************************* + * Copyright (c) 2008 Institute for Software, HSR Hochschule fuer Technik + * Rapperswil, University of applied sciences and others + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Institute for Software - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.ui.refactoring; + +import org.eclipse.osgi.util.NLS; + +public final class Messages extends NLS { + + private static final String BUNDLE_NAME = "org.eclipse.cdt.internal.ui.refactoring.messages";//$NON-NLS-1$ + + private Messages() { + // Do not instantiate + } + + public static String DeleteFileChange_0; + public static String DeleteFileChange_1; + public static String HSRRefactoring_name; + public static String HSRRefactoring_PM_LoadTU; + public static String HSRRefactoring_PM_CheckTU; + public static String HSRRefactoring_PM_InitRef; + public static String HSRRefactoring_PM_ParseTU; + public static String HSRRefactoring_PM_MergeComments; + public static String HSRRefactoring_CanceledByUser; + public static String HSRRefactoring_CompileErrorInTU; + public static String AddDeclarationNodeToClassChange_AddDeclaration; + public static String CreateFileChange_CreateFile; + public static String CreateFileChange_UnknownLoc; + public static String CreateFileChange_FileExists; + public static String HSRRefactoring_SelectionNotValid; + public static String HSRRefactoring_CantLoadTU; + public static String HSRRefactoring_Ambiguity; + public static String NO_FILE; + + static { + NLS.initializeMessages(BUNDLE_NAME, Messages.class); + } +} diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/MethodContext.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/MethodContext.java new file mode 100644 index 00000000000..5d6805111f4 --- /dev/null +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/MethodContext.java @@ -0,0 +1,202 @@ +/******************************************************************************* + * Copyright (c) 2008 Institute for Software, HSR Hochschule fuer Technik + * Rapperswil, University of applied sciences and others + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Institute for Software - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.ui.refactoring; + +import org.eclipse.cdt.core.dom.ast.DOMException; +import org.eclipse.cdt.core.dom.ast.IASTName; +import org.eclipse.cdt.core.dom.ast.IASTNode; +import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration; +import org.eclipse.cdt.core.dom.ast.IBinding; +import org.eclipse.cdt.core.dom.ast.IScope; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTQualifiedName; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTVisiblityLabel; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPBase; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPMember; +import org.eclipse.cdt.ui.CUIPlugin; + +import org.eclipse.cdt.internal.core.dom.parser.ASTInternal; +import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTVisibilityLabel; +import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInternalBinding; + +public class MethodContext { + public enum ContextType{ NONE, FUNCTION, METHOD } + + private ContextType type; + private IASTName declarationName; + private ICPPASTQualifiedName qname; + + public ContextType getType() { + return type; + } + + public void setType(ContextType type) { + this.type = type; + } + + public void setMethodDeclarationName(IASTName tmpname) { + this.declarationName=tmpname; + } + + public IASTName getMethodDeclarationName(){ + return declarationName; + } + + public IASTSimpleDeclaration getMethodDeclaration(){ + IASTNode parent = declarationName.getParent().getParent(); + if (parent instanceof IASTSimpleDeclaration) { + return (IASTSimpleDeclaration) parent; + } else { + return null; + } + } + + public ICPPASTVisiblityLabel getMethodDeclarationASTVisibility(){ + ICPPASTVisiblityLabel label = new CPPASTVisibilityLabel(); + ICPPMember member = ((ICPPMember)qname.resolveBinding()); + + try { + label.setVisibility(member.getVisibility()); + } catch (DOMException e) { + CUIPlugin.getDefault().log(e); + } + return label; + } + + public Visibility getMethodDeclarationVisibility(){ + return Visibility.getVisibility(declarationName); + } + + public void setMethodQName(ICPPASTQualifiedName qname) { + this.qname = qname; + } + + public ICPPASTQualifiedName getMethodQName() { + return qname; + } + + public static boolean isSameClass(ICPPASTQualifiedName qname1, ICPPASTQualifiedName qname2) { + ICPPInternalBinding bind1 = getClassBinding(qname1); + ICPPInternalBinding bind2 = getClassBinding(qname2); + return isSameClass(bind1,bind2); + } + + public static boolean isSameOrSubClass(MethodContext context1, MethodContext contextOfSameOrSubclass) { + ICPPInternalBinding bind1 = getICPPInternalBinding(context1); + ICPPInternalBinding subclassBind = getICPPInternalBinding(contextOfSameOrSubclass); + if(isSameClass(bind1,subclassBind)){ + return true; + } else { + return isSubclass(bind1,subclassBind); + } + } + + private static boolean isSubclass(ICPPInternalBinding bind1, ICPPInternalBinding subclassBind) { + if (subclassBind instanceof ICPPClassType) { + ICPPClassType classType = (ICPPClassType) subclassBind; + ICPPBase[] bases; + try { + bases = classType.getBases(); + } catch (DOMException e) { + return false; + } + for (ICPPBase base : bases) { + if(isSameClass(base,bind1)){ + return true; + } + } + } + return false; + } + + public static boolean isSameClass(MethodContext context1, MethodContext context2) { + ICPPInternalBinding bind1 = getICPPInternalBinding(context1); + ICPPInternalBinding bind2 = getICPPInternalBinding(context2); + + return isSameClass(bind1,bind2); + } + + private static boolean isSameClass(ICPPBase base, ICPPInternalBinding bind2) { + try { + IBinding bind1 = base.getBaseClass(); + IScope scope1 = bind1.getScope(); + if(scope1 == null) + return false; + IASTNode node1 = ASTInternal.getPhysicalNodeOfScope(scope1); + + IScope scope2 = bind2.getScope(); + if(scope2 == null) + return false; + IASTNode node2 = ASTInternal.getPhysicalNodeOfScope(scope2); + + if( node1.equals(node2) ){ + if (bind1 instanceof ICPPInternalBinding) { + ICPPInternalBinding bind1int = (ICPPInternalBinding) bind1; + return bind1int.getDefinition().equals(bind2.getDefinition()); + } else { + return false; + } + } else { + return false; + } + } catch (DOMException e) { + return false; + } + } + + private static boolean isSameClass(ICPPInternalBinding bind1, ICPPInternalBinding bind2) { + try { + IScope scope1 = bind1.getScope(); + if(scope1 == null) + return false; + IASTNode node1 = ASTInternal.getPhysicalNodeOfScope(scope1); + + IScope scope2 = bind2.getScope(); + if(scope2 == null) + return false; + IASTNode node2 = ASTInternal.getPhysicalNodeOfScope(scope2); + + if( node1.equals(node2) ){ + return bind1.getDefinition().equals(bind2.getDefinition()); + } else { + return false; + } + } catch (DOMException e) { + return false; + } + } + + public static ICPPInternalBinding getICPPInternalBinding(MethodContext context) { + IASTName decl = context.getMethodDeclarationName(); + IASTNode node = decl; + while(node != null){ + if (node instanceof ICPPASTCompositeTypeSpecifier) { + ICPPASTCompositeTypeSpecifier type = (ICPPASTCompositeTypeSpecifier) node; + IASTName classname = type.getName(); + ICPPInternalBinding bind = (ICPPInternalBinding)classname.resolveBinding(); + + return bind; + } + + node = node.getParent(); + } + + return null; + } + + private static ICPPInternalBinding getClassBinding(ICPPASTQualifiedName qname){ + IASTName classname = qname.getNames()[qname.getNames().length - 2]; + ICPPInternalBinding bind = (ICPPInternalBinding)classname.resolveBinding(); + return bind; + } +} diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/ModificationCollector.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/ModificationCollector.java new file mode 100644 index 00000000000..3347c0ac3f7 --- /dev/null +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/ModificationCollector.java @@ -0,0 +1,69 @@ +/******************************************************************************* + * Copyright (c) 2008 Institute for Software, HSR Hochschule fuer Technik + * Rapperswil, University of applied sciences and others + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Institute for Software - initial API and implementation + *******************************************************************************/ + +package org.eclipse.cdt.internal.ui.refactoring; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; + +import org.eclipse.ltk.core.refactoring.Change; +import org.eclipse.ltk.core.refactoring.CompositeChange; + +import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit; +import org.eclipse.cdt.core.dom.rewrite.ASTRewrite; + +/** + * @author Mirko Stocker + * + * A ModificationCollector can be passed through a refactoring and manages the rewriters + * and additional changes a refactoring can create. + */ +public class ModificationCollector { + + // Each Translationunit can have only one ASTRewrite + private final Map rewriters = new HashMap(); + + private Collection changes; + + public ASTRewrite rewriterForTranslationUnit(IASTTranslationUnit unit) { + if(! rewriters.containsKey(unit)) { + rewriters.put(unit, ASTRewrite.create(unit)); + } + + return rewriters.get(unit); + } + + // Creating new files doesn't concern the rewriter, the refactorings can add them here as needed. + public void addFileChange(CreateFileChange change) { + if(changes == null) { + changes = new ArrayList(); + } + changes.add(change); + } + + public CompositeChange createFinalChange() { + // Synthetic changes aren't displayed and therefore don't need a name + CompositeChange result = new CompositeChange(""); //$NON-NLS-1$ + result.markAsSynthetic(); + + if(changes != null) + result.addAll(changes.toArray(new Change[changes.size()])); + + for (ASTRewrite each : rewriters.values()) { + result.add(each.rewriteAST()); + } + + return result; + } +} diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/NameNVisibilityInformation.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/NameNVisibilityInformation.java new file mode 100644 index 00000000000..f76113d5ec9 --- /dev/null +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/NameNVisibilityInformation.java @@ -0,0 +1,52 @@ +/******************************************************************************* + * Copyright (c) 2008 Institute for Software, HSR Hochschule fuer Technik + * Rapperswil, University of applied sciences and others + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Institute for Software - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.ui.refactoring; + +import java.util.Vector; + +import org.eclipse.cdt.internal.ui.refactoring.utils.VisibilityEnum; + +public class NameNVisibilityInformation { + + private String name = ""; //$NON-NLS-1$ + private VisibilityEnum visibility = VisibilityEnum.v_public; + private final Vector usedNames = new Vector(); + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public VisibilityEnum getVisibility() { + return visibility; + } + + public void setVisibility(VisibilityEnum visibility) { + this.visibility = visibility; + } + + public Vector getUsedNames(){ + return usedNames; + } + + public void addNameToUsedNames(String name) { + usedNames.add(name); + } + + public void addNamesToUsedNames(Vector names) { + usedNames.addAll(names); + } + +} diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/RefactoringRunner.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/RefactoringRunner.java new file mode 100644 index 00000000000..004224f4aff --- /dev/null +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/RefactoringRunner.java @@ -0,0 +1,42 @@ +/******************************************************************************* + * Copyright (c) 2008 Institute for Software, HSR Hochschule fuer Technik + * Rapperswil, University of applied sciences and others + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Institute for Software - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.ui.refactoring; + +import org.eclipse.core.resources.IFile; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.PlatformUI; + +/** + * @author Emanuel Graf + * + */ +public abstract class RefactoringRunner { + + protected IFile file; + protected ISelection selection; + protected IWorkbenchWindow window; + + public RefactoringRunner(IFile file, ISelection selection, IWorkbenchWindow window) { + super(); + this.file = file; + this.selection = selection; + if(window != null) { + this.window = window; + }else { + this.window = PlatformUI.getWorkbench().getActiveWorkbenchWindow(); + } + } + + public abstract void run(); + +} diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/UndoCTextFileChange.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/UndoCTextFileChange.java new file mode 100644 index 00000000000..294ae79505d --- /dev/null +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/UndoCTextFileChange.java @@ -0,0 +1,89 @@ +/******************************************************************************* + * Copyright (c) 2006, 2008 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - Initial API and implementation + * Markus Schorn (Wind River Systems) + *******************************************************************************/ +package org.eclipse.cdt.internal.ui.refactoring; + +import org.eclipse.core.resources.IFile; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.NullProgressMonitor; +import org.eclipse.jface.text.BadLocationException; +import org.eclipse.jface.text.IDocument; +import org.eclipse.ltk.core.refactoring.Change; +import org.eclipse.ltk.core.refactoring.ContentStamp; +import org.eclipse.ltk.core.refactoring.UndoTextFileChange; +import org.eclipse.text.edits.MalformedTreeException; +import org.eclipse.text.edits.TextEdit; +import org.eclipse.text.edits.UndoEdit; + +import org.eclipse.cdt.core.CCorePlugin; +import org.eclipse.cdt.core.model.CoreModel; +import org.eclipse.cdt.core.model.IBuffer; +import org.eclipse.cdt.core.model.ICElement; +import org.eclipse.cdt.core.model.ITranslationUnit; +import org.eclipse.cdt.core.model.IWorkingCopy; + +/** + * UndoCTextFileChange that uses a working copy in order to generate CModel events. + * @author janees + */ +public class UndoCTextFileChange + extends UndoTextFileChange { + + UndoEdit mUndoEdit = null; + + public UndoCTextFileChange(String name, IFile file, UndoEdit undo, ContentStamp stamp, int saveMode) { + super(name, file, undo, stamp, saveMode); + mUndoEdit = undo; + } + + /* + * (non-Javadoc) + * @see org.eclipse.ltk.core.refactoring.UndoTextFileChange#perform(org.eclipse.core.runtime.IProgressMonitor) + */ + @Override + public Change perform(IProgressMonitor pm) + throws CoreException { + if (pm == null){ + pm= new NullProgressMonitor(); + } + Object obj = getModifiedElement(); + if(!(obj instanceof IFile)){ + throw new IllegalArgumentException(); + } + final IFile file = (IFile) obj; + ICElement element = CoreModel.getDefault().create(file); + if (!(element instanceof ITranslationUnit)) { + return super.perform(pm); + } + + final ITranslationUnit tu = (ITranslationUnit) element; + IWorkingCopy wc= tu.getWorkingCopy(pm, DocumentAdapter.FACTORY); + final IBuffer buffer= wc.getBuffer(); + assert buffer instanceof DocumentAdapter; + if (buffer instanceof DocumentAdapter) { + IDocument document= ((DocumentAdapter) buffer).getDocument(); + try { + UndoEdit redo= mUndoEdit.apply(document, TextEdit.CREATE_UNDO); + wc.commit(false, pm); + return new UndoCTextFileChange(getName(), file, redo, null, getSaveMode()); + } catch (MalformedTreeException e) { + CCorePlugin.log(e); + } catch (BadLocationException e) { + CCorePlugin.log(e); + } + finally { + wc.destroy(); + } + } + return null; + } +} diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/Visibility.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/Visibility.java new file mode 100644 index 00000000000..1093192d386 --- /dev/null +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/Visibility.java @@ -0,0 +1,92 @@ +/******************************************************************************* + * Copyright (c) 2008 Institute for Software, HSR Hochschule fuer Technik + * Rapperswil, University of applied sciences and others + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Institute for Software - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.ui.refactoring; + +import org.eclipse.cdt.core.dom.ast.DOMException; +import org.eclipse.cdt.core.dom.ast.IASTName; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTVisiblityLabel; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPMember; + +public class Visibility { + + /** + * The visibility public. + */ + public static final Visibility PUBLIC = new Visibility(){ + @Override + public String stringValue(){ + return "public"; //$NON-NLS-1$ + } + }; + + /** + * The visibility protected. + */ + public static final Visibility PROTECTED = new Visibility(){ + @Override + public String stringValue(){ + return "protected"; //$NON-NLS-1$ + } + }; + + /** + * The visibility private. + */ + public static final Visibility PRIVATE = new Visibility(){ + @Override + public String stringValue(){ + return "private"; //$NON-NLS-1$ + } + }; + + /** + * The visibility unknown, cause of parsing error. + */ + public static final Visibility UNKNOWN = new Visibility(){ }; + + + + private Visibility(){ } + + public static Visibility getVisibility(IASTName name){ + try { + ICPPMember member = ((ICPPMember)name.resolveBinding()); + + switch (member.getVisibility()){ + case ICPPASTVisiblityLabel.v_public: + return PUBLIC; + case ICPPASTVisiblityLabel.v_protected: + return PROTECTED; + case ICPPASTVisiblityLabel.v_private: + return PRIVATE; + default: + return UNKNOWN; + } + + } catch (DOMException e) { + return UNKNOWN; + } catch (RuntimeException e){ + return UNKNOWN; + } + } + + public String stringValue(){ + return ""; //$NON-NLS-1$ + } + + @Override + public String toString() { + return stringValue(); + } + + +} diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/dialogs/CTextEditChangePreviewViewer.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/dialogs/CTextEditChangePreviewViewer.java new file mode 100644 index 00000000000..937262c1500 --- /dev/null +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/dialogs/CTextEditChangePreviewViewer.java @@ -0,0 +1,265 @@ +/******************************************************************************* + * Copyright (c) 2008 Institute for Software, HSR Hochschule fuer Technik + * Rapperswil, University of applied sciences and others + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Institute for Software - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.ui.refactoring.dialogs; + +import java.io.ByteArrayInputStream; +import java.io.InputStream; +import java.io.UnsupportedEncodingException; + +import org.eclipse.compare.CompareConfiguration; +import org.eclipse.compare.CompareViewerPane; +import org.eclipse.compare.IEncodedStreamContentAccessor; +import org.eclipse.compare.IResourceProvider; +import org.eclipse.compare.ITypedElement; +import org.eclipse.compare.contentmergeviewer.IMergeViewerContentProvider; +import org.eclipse.compare.structuremergeviewer.DiffNode; +import org.eclipse.compare.structuremergeviewer.ICompareInput; +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.NullProgressMonitor; +import org.eclipse.jface.preference.IPreferenceStore; +import org.eclipse.jface.text.TextViewer; +import org.eclipse.jface.text.source.SourceViewer; +import org.eclipse.jface.viewers.Viewer; +import org.eclipse.ltk.core.refactoring.Change; +import org.eclipse.ltk.ui.refactoring.ChangePreviewViewerInput; +import org.eclipse.ltk.ui.refactoring.IChangePreviewViewer; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; + +import org.eclipse.cdt.ui.CElementLabelProvider; +import org.eclipse.cdt.ui.CUIPlugin; +import org.eclipse.cdt.ui.refactoring.CTextFileChange; + +import org.eclipse.cdt.internal.ui.compare.CMergeViewer; +import org.eclipse.cdt.internal.ui.text.CSourceViewerConfiguration; +import org.eclipse.cdt.internal.ui.text.CTextTools; + +/** + * @author Emanuel Graf + * + */ +public class CTextEditChangePreviewViewer implements IChangePreviewViewer { + + private CPPMergeViewer viewer; + private CTextEditChangePane viewerPane; + private CTextEditChangePreviewViewerContentProvider textEditChangeContentProvider; + + private static class CTextEditChangePane extends CompareViewerPane{ + + /** + * @param parent + * @param style + */ + public CTextEditChangePane(Composite parent, int style) { + super(parent, style); + } + + } + + private class CPPMergeViewer extends CMergeViewer{ + + /** + * @param parent + * @param styles + * @param mp + */ + public CPPMergeViewer(Composite parent, int styles, CompareConfiguration mp) { + super(parent, styles, mp); + } + + @Override + protected CSourceViewerConfiguration getSourceViewerConfiguration() { + CTextTools tools= CUIPlugin.getDefault().getTextTools(); + IPreferenceStore store= CUIPlugin.getDefault().getCombinedPreferenceStore(); + return new CSourceViewerConfiguration(tools.getColorManager(), store, null, tools.getDocumentPartitioning()); + } + + @Override + protected void configureTextViewer(TextViewer textViewer) { + if (textViewer instanceof SourceViewer) { + ((SourceViewer)textViewer).configure(getSourceViewerConfiguration()); + } + } + + + } + + + private class CTextEditChangePreviewViewerContentProvider implements IMergeViewerContentProvider{ + + public Object getAncestorContent(Object input) { + if (input instanceof ICompareInput) + return ((ICompareInput) input).getAncestor(); + return null; + } + + public Image getAncestorImage(Object input) { + if (input instanceof ICompareInput) { + ITypedElement ancestor = ((ICompareInput) input).getAncestor(); + if(ancestor != null) { + return ancestor.getImage(); + } + } + return null; + } + + public String getAncestorLabel(Object input) { + if (input instanceof ICompareInput) { + ITypedElement ancestor = ((ICompareInput) input).getAncestor(); + if(ancestor != null) { + return ancestor.getName(); + } + } + return null; + } + + public Object getLeftContent(Object input) { + if (input instanceof ICompareInput) + return ((ICompareInput) input).getLeft(); + return null; + } + + public Image getLeftImage(Object input) { + if (input instanceof ICompareInput) + return ((ICompareInput) input).getLeft().getImage(); + return null; + } + + public String getLeftLabel(Object input) { + return Messages.CTextEditChangePreviewViewer_OrgSource; + } + + public Object getRightContent(Object input) { + if (input instanceof ICompareInput) + return ((ICompareInput) input).getRight(); + return null; + } + + public Image getRightImage(Object input) { + if (input instanceof ICompareInput) + return ((ICompareInput) input).getRight().getImage(); + return null; + } + + public String getRightLabel(Object input) { + return Messages.CTextEditChangePreviewViewer_RefactoredSource; + } + + public boolean isLeftEditable(Object input) { + return false; + } + + public boolean isRightEditable(Object input) { + return false; + } + + public void saveLeftContent(Object input, byte[] bytes) { + //No Edits + } + + public void saveRightContent(Object input, byte[] bytes) { + //No Edits + } + + public boolean showAncestor(Object input) { + //no Ancestor + return false; + } + + public void dispose() { + // + } + + public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { + //Nothing to do + } + + } + + private static class CompareElement implements ITypedElement, IEncodedStreamContentAccessor, IResourceProvider { + private static final String ENCODING= "UTF-8"; //$NON-NLS-1$ + private final String fContent; + private final String fType; + private final IResource fResource; + public CompareElement(String content, String type, IResource resource) { + fContent= content; + fType= type; + fResource= resource; + } + public String getName() { + return ""; //$NON-NLS-1$ + } + public Image getImage() { + return null; + } + public String getType() { + return fType; + } + public InputStream getContents() throws CoreException { + try { + return new ByteArrayInputStream(fContent.getBytes(ENCODING)); + } catch (UnsupportedEncodingException e) { + return new ByteArrayInputStream(fContent.getBytes()); + } + } + public String getCharset() { + return ENCODING; + } + public IResource getResource() { + return fResource; + } + } + + public void createControl(Composite parent) { + CompareConfiguration compConfig = new CompareConfiguration(); + compConfig.setLeftEditable(false); + compConfig.setRightEditable(false); + viewerPane = new CTextEditChangePane(parent, SWT.BORDER | SWT.FLAT); + viewer = new CPPMergeViewer(viewerPane,SWT.MULTI | SWT.FULL_SELECTION, compConfig); + textEditChangeContentProvider = new CTextEditChangePreviewViewerContentProvider(); + viewer.setContentProvider(textEditChangeContentProvider); + viewerPane.setContent(viewer.getControl()); + } + + public Control getControl() { + return viewerPane; + } + + public void setInput(ChangePreviewViewerInput input) { + try { + Change change= input.getChange(); + if (change instanceof CTextFileChange) { + CTextFileChange editChange= (CTextFileChange)change; + setInput(editChange, editChange.getCurrentContent(new NullProgressMonitor()), editChange.getPreviewContent(new NullProgressMonitor()), editChange.getTextType()); + return; + } else { + viewer.setInput(null); + } + } catch (CoreException e) { + viewer.setInput(null); + } + } + + private void setInput(CTextFileChange change, String left, String right, String type) { + IFile resource = change.getFile(); + viewerPane.setText(resource.getName()); + viewerPane.setImage(new CElementLabelProvider().getImage(resource)); + viewer.setInput(new DiffNode( + new CompareElement(left, type, resource), + new CompareElement(right, type, resource))); + } + +} diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/dialogs/CreateFileChangePreview.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/dialogs/CreateFileChangePreview.java new file mode 100644 index 00000000000..3e2ff1ecb46 --- /dev/null +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/dialogs/CreateFileChangePreview.java @@ -0,0 +1,86 @@ +/******************************************************************************* + * Copyright (c) 2008 Institute for Software, HSR Hochschule fuer Technik + * Rapperswil, University of applied sciences and others + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Institute for Software - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.ui.refactoring.dialogs; + +import org.eclipse.core.runtime.Assert; +import org.eclipse.jface.dialogs.Dialog; +import org.eclipse.jface.preference.IPreferenceStore; +import org.eclipse.jface.text.Document; +import org.eclipse.jface.text.source.SourceViewer; +import org.eclipse.ltk.core.refactoring.Change; +import org.eclipse.ltk.ui.refactoring.ChangePreviewViewerInput; +import org.eclipse.ltk.ui.refactoring.IChangePreviewViewer; +import org.eclipse.swt.SWT; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; + +import org.eclipse.cdt.ui.CUIPlugin; + +import org.eclipse.cdt.internal.ui.editor.CSourceViewer; +import org.eclipse.cdt.internal.ui.refactoring.CreateFileChange; +import org.eclipse.cdt.internal.ui.text.CSourceViewerConfiguration; +import org.eclipse.cdt.internal.ui.text.CTextTools; +import org.eclipse.cdt.internal.ui.util.ViewerPane; + +/** + * @author Emanuel Graf + * + */ +public class CreateFileChangePreview implements IChangePreviewViewer { + + private static class CreateFileChangePane extends ViewerPane{ + + /** + * @param parent + * @param style + */ + public CreateFileChangePane(Composite parent, int style) { + super(parent, style); + } + + } + + private CreateFileChangePane control; + private SourceViewer srcViewer; + private CTextTools textTools; + + public void createControl(Composite parent) { + control = new CreateFileChangePane(parent, SWT.BORDER | SWT.FLAT); + Dialog.applyDialogFont(control); + srcViewer= new CSourceViewer(control, null, null, false, SWT.V_SCROLL | SWT.H_SCROLL | SWT.MULTI | SWT.FULL_SELECTION, CUIPlugin.getDefault().getPreferenceStore()); + textTools = CUIPlugin.getDefault().getTextTools(); + IPreferenceStore store= CUIPlugin.getDefault().getCombinedPreferenceStore(); + CSourceViewerConfiguration sourceViewerConfiguration = new CSourceViewerConfiguration(textTools.getColorManager(), store, null, textTools.getDocumentPartitioning()); + srcViewer.configure(sourceViewerConfiguration); + srcViewer.setEditable(false); + control.setContent(srcViewer.getControl()); + } + + public Control getControl() { + return control; + } + + public void setInput(ChangePreviewViewerInput input) { + Assert.isNotNull(input); + if(control != null) { + Change change = input.getChange(); + if (change instanceof CreateFileChange) { + CreateFileChange createFileChange = (CreateFileChange) change; + control.setText(createFileChange.getName()); + Document document = new Document(createFileChange.getSource()); + textTools.setupCDocument(document); + srcViewer.setDocument(document); + } + } + } + +} diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/dialogs/ExtractInputPage.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/dialogs/ExtractInputPage.java new file mode 100644 index 00000000000..ddabf5ab613 --- /dev/null +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/dialogs/ExtractInputPage.java @@ -0,0 +1,95 @@ +/******************************************************************************* + * Copyright (c) 2008 Institute for Software, HSR Hochschule fuer Technik + * Rapperswil, University of applied sciences and others + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Institute for Software - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.ui.refactoring.dialogs; + + +import org.eclipse.ltk.ui.refactoring.UserInputWizardPage; +import org.eclipse.osgi.util.NLS; +import org.eclipse.swt.events.KeyAdapter; +import org.eclipse.swt.events.KeyEvent; +import org.eclipse.swt.events.MouseAdapter; +import org.eclipse.swt.events.MouseEvent; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; + +import org.eclipse.cdt.internal.ui.refactoring.NameNVisibilityInformation; +import org.eclipse.cdt.internal.ui.refactoring.utils.IdentifierHelper; +import org.eclipse.cdt.internal.ui.refactoring.utils.IdentifierResult; +import org.eclipse.cdt.internal.ui.refactoring.utils.VisibilityEnum; + +/** + * @author Emanuel Graf + * + */ +public abstract class ExtractInputPage extends UserInputWizardPage { + + protected NameAndVisibilityComposite control; + protected NameNVisibilityInformation info; + protected String label = Messages.ExtractInputPage_ReplaceInSubclass; + protected String errorLabel = Messages.ExtractInputPage_EnterName; + + public ExtractInputPage(String name, NameNVisibilityInformation info) { + super(name); + this.info = info; + } + + public void createControl(Composite parent) { + control = new NameAndVisibilityComposite(parent, label); + setTitle(getName()); + setPageComplete(false); + control.getConstantNameText().addKeyListener(new KeyAdapter(){ + + @Override + public void keyReleased(KeyEvent e) { + info.setName(control.getConstantNameText().getText()); + checkName(); + } + + }); + + for (Control buttons : control.getVisibiltyGroup().getChildren()) { + buttons.addMouseListener(new MouseAdapter() { + + @Override + public void mouseUp(MouseEvent e) { + String text = ((Button)e.getSource()).getText(); + visibilityChange(text); + } + + }); + } + + checkName(); + setControl(control); + } + + protected void checkName() { + String methodName = control.getConstantNameText().getText(); + IdentifierResult result = IdentifierHelper.checkIdentifierName(methodName); + if(result.isCorrect()){ + setErrorMessage(null); + setPageComplete(true); + } + else{ + setErrorMessage(NLS.bind(Messages.ExtractInputPage_CheckName, result.getMessage())); + setPageComplete(false); + } + } + + abstract protected void verifyName(String name); + + protected void visibilityChange(String visibilityText) { + info.setVisibility(VisibilityEnum.getEnumForStringRepresentation(visibilityText)); + } + +} diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/dialogs/LabeledTextField.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/dialogs/LabeledTextField.java new file mode 100644 index 00000000000..691b6d7fd59 --- /dev/null +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/dialogs/LabeledTextField.java @@ -0,0 +1,60 @@ +/******************************************************************************* + * Copyright (c) 2008 Institute for Software, HSR Hochschule fuer Technik + * Rapperswil, University of applied sciences and others + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Institute for Software - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.ui.refactoring.dialogs; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Text; + +/** + * @author Mirko Stocker + * + */ +public class LabeledTextField extends Composite { + + private final Text textField; + + public LabeledTextField(Composite parent, String labelName, String textContent) { + super(parent, SWT.NONE); + + GridLayout layout = new GridLayout(); + layout.numColumns = 2; + layout.marginWidth = 0; + setLayout(layout); + + Label label = new Label(this, SWT.NONE); + label.setText(labelName); + label.setLayoutData(new GridData()); + + textField = new Text(this, SWT.BORDER |SWT.SINGLE); + textField.setText(textContent); + textField.selectAll(); + GridData textData = new GridData(GridData.FILL_HORIZONTAL); + textData.grabExcessHorizontalSpace = true; + textField.setLayoutData(textData); + } + + public LabeledTextField(Composite parent, String labelName) { + this(parent, labelName, ""); //$NON-NLS-1$ + } + + public Text getText() { + return textField; + } + + public String getFieldContent(){ + return textField.getText(); + } +} diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/dialogs/Messages.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/dialogs/Messages.java new file mode 100644 index 00000000000..be8666fcec7 --- /dev/null +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/dialogs/Messages.java @@ -0,0 +1,34 @@ +/******************************************************************************* + * Copyright (c) 2008 Institute for Software, HSR Hochschule fuer Technik + * Rapperswil, University of applied sciences and others + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Institute for Software - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.ui.refactoring.dialogs; + +import org.eclipse.osgi.util.NLS; + +public final class Messages extends NLS { + + private static final String BUNDLE_NAME = "org.eclipse.cdt.internal.ui.refactoring.dialogs.messages";//$NON-NLS-1$ + + private Messages() { + // Do not instantiate + } + + public static String CTextEditChangePreviewViewer_OrgSource; + public static String CTextEditChangePreviewViewer_RefactoredSource; + public static String ExtractInputPage_ReplaceInSubclass; + public static String ExtractInputPage_EnterName; + public static String ExtractInputPage_CheckName; + public static String VisibilitySelectionPanel_AccessModifier; + + static { + NLS.initializeMessages(BUNDLE_NAME, Messages.class); + } +} diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/dialogs/NameAndVisibilityComposite.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/dialogs/NameAndVisibilityComposite.java new file mode 100644 index 00000000000..80db77eaecb --- /dev/null +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/dialogs/NameAndVisibilityComposite.java @@ -0,0 +1,73 @@ +/******************************************************************************* + * Copyright (c) 2008 Institute for Software, HSR Hochschule fuer Technik + * Rapperswil, University of applied sciences and others + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Institute for Software - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.ui.refactoring.dialogs; + +/** + * @author Thomas Corbat + * + */ +import org.eclipse.swt.SWT; +import org.eclipse.swt.layout.FillLayout; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Group; +import org.eclipse.swt.widgets.Text; + +import org.eclipse.cdt.internal.ui.refactoring.utils.VisibilityEnum; + +public class NameAndVisibilityComposite extends Composite { + + private LabeledTextField constantName; + private final String labelName; + private final VisibilitySelectionPanel visibilityPanel; + + public NameAndVisibilityComposite(Composite parent, String labelName) { + this(parent, labelName, VisibilityEnum.v_public); + } + + public NameAndVisibilityComposite(Composite parent, String labelName, VisibilityEnum defaultVisibility){ + + super(parent, SWT.NONE); + + this.labelName = labelName; + + setLayout(new GridLayout()); + + createNewMethodNameComposite(this); + visibilityPanel = new VisibilitySelectionPanel(this, defaultVisibility,SWT.NONE); + } + + + public Text getConstantNameText() { + return constantName.getText(); + } + + public Group getVisibiltyGroup() { + return visibilityPanel.getGroup(); + } + + public void visibilityPanelsetVisible(boolean visible) { + visibilityPanel.setVisible(visible); + } + + + private void createNewMethodNameComposite(Composite control) { + Composite methodNameComposite = new Composite(control, SWT.NONE); + FillLayout compositeLayout = new FillLayout(SWT.HORIZONTAL); + GridData gridData = new GridData(SWT.FILL,SWT.BEGINNING, true, false); + gridData.horizontalAlignment = GridData.FILL; + methodNameComposite.setLayoutData(gridData); + methodNameComposite.setLayout(compositeLayout); + constantName = new LabeledTextField(methodNameComposite, labelName); + } +} diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/dialogs/VisibilitySelectionPanel.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/dialogs/VisibilitySelectionPanel.java new file mode 100644 index 00000000000..e7b90ccb6d1 --- /dev/null +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/dialogs/VisibilitySelectionPanel.java @@ -0,0 +1,96 @@ +/******************************************************************************* + * Copyright (c) 2008 Institute for Software, HSR Hochschule fuer Technik + * Rapperswil, University of applied sciences and others + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Institute for Software - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.ui.refactoring.dialogs; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.layout.FillLayout; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.RowLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Group; + +import org.eclipse.cdt.internal.ui.refactoring.utils.VisibilityEnum; + +/** + * @author Thomas Corbat + * + */ +public class VisibilitySelectionPanel extends Composite { + + + private Button publicAccessRadioButton; + private Button protectedAccessRadioButton; + private Button privateAccessRadioButton; + private Group accessModifierGroup; + + public VisibilitySelectionPanel(Composite parent, VisibilityEnum defaultVisibility, int style) { + super(parent, style); + + FillLayout compositeLayout = new FillLayout(SWT.HORIZONTAL); + setLayout(compositeLayout); + GridData gridData = new GridData(SWT.FILL,SWT.BEGINNING, true, false); + gridData.horizontalAlignment = GridData.FILL; + setLayoutData(gridData); + + createAccessModifierComposite(this); + setSelected(defaultVisibility); + + } + + private void createAccessModifierComposite(Composite control) { + + accessModifierGroup = new Group(this, SWT.SHADOW_NONE ); + RowLayout groupLayout = new RowLayout(SWT.HORIZONTAL); + groupLayout.fill = true; + accessModifierGroup.setLayout(groupLayout); + accessModifierGroup.setText(Messages.VisibilitySelectionPanel_AccessModifier); + + publicAccessRadioButton = new Button(accessModifierGroup, SWT.RADIO | SWT.LEFT); + publicAccessRadioButton.setText(VisibilityEnum.v_public.toString()); + + protectedAccessRadioButton = new Button(accessModifierGroup, SWT.RADIO | SWT.LEFT); + protectedAccessRadioButton.setText(VisibilityEnum.v_protected.toString()); + + privateAccessRadioButton = new Button(accessModifierGroup, SWT.RADIO | SWT.LEFT); + privateAccessRadioButton.setText(VisibilityEnum.v_private.toString()); + + } + + private void setSelected(VisibilityEnum defaultVisibility) { + switch (defaultVisibility){ + case v_public: + publicAccessRadioButton.setSelection(true); + break; + case v_protected: + protectedAccessRadioButton.setSelection(true); + break; + case v_private: + privateAccessRadioButton.setSelection(true); + break; + } + } + + public Group getGroup() { + return accessModifierGroup; + } + + @Override + public void setEnabled(boolean enabled){ + accessModifierGroup.setEnabled(enabled); + publicAccessRadioButton.setEnabled(enabled); + protectedAccessRadioButton.setEnabled(enabled); + privateAccessRadioButton.setEnabled(enabled); + super.setEnabled(enabled); + } + +} diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/dialogs/messages.properties b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/dialogs/messages.properties new file mode 100644 index 00000000000..0c23f89c629 --- /dev/null +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/dialogs/messages.properties @@ -0,0 +1,17 @@ +############################################################################### +# Copyright (c) 2008 Institute for Software, HSR Hochschule fuer Technik +# Rapperswil, University of applied sciences and others +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Eclipse Public License v1.0 +# which accompanies this distribution, and is available at +# http://www.eclipse.org/legal/epl-v10.html +# +# Contributors: +# Institute for Software - initial API and implementation +############################################################################### +CTextEditChangePreviewViewer_OrgSource=Original Source +CTextEditChangePreviewViewer_RefactoredSource=Refactored Source +ExtractInputPage_ReplaceInSubclass=Replace in subclass: +ExtractInputPage_EnterName=Enter a name +ExtractInputPage_CheckName=Check Name: {0} +VisibilitySelectionPanel_AccessModifier=&Access modifier: diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/extractconstant/ExtractConstantRefactoring.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/extractconstant/ExtractConstantRefactoring.java new file mode 100644 index 00000000000..37a8efd89a8 --- /dev/null +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/extractconstant/ExtractConstantRefactoring.java @@ -0,0 +1,365 @@ +/******************************************************************************* + * Copyright (c) 2007 2008 Institute for Software, HSR Hochschule fuer Technik + * Rapperswil, University of applied sciences and others + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Institute for Software - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.ui.refactoring.extractconstant; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Vector; + +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.ResourcesPlugin; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.OperationCanceledException; +import org.eclipse.core.runtime.Path; +import org.eclipse.core.runtime.SubMonitor; +import org.eclipse.jface.text.ITextSelection; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.ltk.core.refactoring.RefactoringStatus; +import org.eclipse.text.edits.TextEditGroup; + +import org.eclipse.cdt.core.dom.ast.IASTDeclSpecifier; +import org.eclipse.cdt.core.dom.ast.IASTDeclaration; +import org.eclipse.cdt.core.dom.ast.IASTDeclarator; +import org.eclipse.cdt.core.dom.ast.IASTExpression; +import org.eclipse.cdt.core.dom.ast.IASTFunctionDefinition; +import org.eclipse.cdt.core.dom.ast.IASTInitializerExpression; +import org.eclipse.cdt.core.dom.ast.IASTLiteralExpression; +import org.eclipse.cdt.core.dom.ast.IASTMacroExpansionLocation; +import org.eclipse.cdt.core.dom.ast.IASTName; +import org.eclipse.cdt.core.dom.ast.IASTNode; +import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclSpecifier; +import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration; +import org.eclipse.cdt.core.dom.ast.IASTUnaryExpression; +import org.eclipse.cdt.core.dom.ast.IBinding; +import org.eclipse.cdt.core.dom.ast.cpp.CPPASTVisitor; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTLiteralExpression; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNamespaceDefinition; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTSimpleDeclSpecifier; +import org.eclipse.cdt.core.dom.rewrite.ASTRewrite; + +import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTDeclarator; +import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTIdExpression; +import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTInitializerExpression; +import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTLiteralExpression; +import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTName; +import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTNamespaceDefinition; +import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTSimpleDeclSpecifier; +import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTSimpleDeclaration; +import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPMethod; + +import org.eclipse.cdt.internal.ui.refactoring.AddDeclarationNodeToClassChange; +import org.eclipse.cdt.internal.ui.refactoring.CRefactoring; +import org.eclipse.cdt.internal.ui.refactoring.MethodContext; +import org.eclipse.cdt.internal.ui.refactoring.ModificationCollector; +import org.eclipse.cdt.internal.ui.refactoring.NameNVisibilityInformation; +import org.eclipse.cdt.internal.ui.refactoring.utils.TranslationUnitHelper; + +public class ExtractConstantRefactoring extends CRefactoring { + + private IASTLiteralExpression target = null; + private final Vector literalsToReplace = new Vector(); + private final NameNVisibilityInformation info; + + public ExtractConstantRefactoring(IFile file, ISelection selection, NameNVisibilityInformation info){ + this(file, selection, info, false); + } + + public ExtractConstantRefactoring(IFile file, ISelection selection, NameNVisibilityInformation info, boolean runHeadless){ + super(file,selection, runHeadless); + this.info = info; + name = Messages.ExtractConstantRefactoring_ExtractConst; + } + + @Override + public RefactoringStatus checkInitialConditions(IProgressMonitor pm) throws CoreException, OperationCanceledException { + SubMonitor sm = SubMonitor.convert(pm, 10); + super.checkInitialConditions(sm.newChild(6)); + + Collection literalExpressionVector = findAllLiterals(); + if(literalExpressionVector.isEmpty()){ + initStatus.addFatalError(Messages.ExtractConstantRefactoring_LiteralMustBeSelected); + return initStatus; + } + sm.worked(1); + + if(isProgressMonitorCanceld(sm, initStatus)) return initStatus; + + ITextSelection textSelection = null; + if (selection instanceof ITextSelection) { + textSelection = (ITextSelection) selection; + } else { + initStatus.addFatalError(Messages.ExtractConstantRefactoring_LiteralMustBeSelected); + return initStatus; + } + sm.worked(1); + + if(isProgressMonitorCanceld(sm, initStatus)) return initStatus; + + //Feststellen das nur einer Markiert ist. + boolean oneMarked = isOneMarked(literalExpressionVector, textSelection); + if(!oneMarked){ + //No or more than one marked + if(target == null){ + //No Selection found; + initStatus.addFatalError(Messages.ExtractConstantRefactoring_NoLiteralSelected); + } else { + //To many selection found + initStatus.addFatalError(Messages.ExtractConstantRefactoring_TooManyLiteralSelected); + } + return initStatus; + } + sm.worked(1); + + if(isProgressMonitorCanceld(sm, initStatus)) return initStatus; + + // Alle Knoten zum ersetzen finden + findAllNodesForReplacement(literalExpressionVector); + + info.addNamesToUsedNames(findAllDeclaredNames()); + sm.done(); + return initStatus; + } + + private Vector findAllDeclaredNames() { + Vectornames = new Vector(); + IASTFunctionDefinition funcDef = getFunctionDefinition(); + ICPPASTCompositeTypeSpecifier comTypeSpec = getCompositeTypeSpecifier(funcDef); + if(comTypeSpec != null) { + for(IASTDeclaration dec : comTypeSpec.getMembers()) { + if (dec instanceof IASTSimpleDeclaration) { + IASTSimpleDeclaration simpDec = (IASTSimpleDeclaration) dec; + for(IASTDeclarator decor : simpDec.getDeclarators()) { + names.add(decor.getName().getRawSignature()); + } + } + } + } + return names; + } + + private ICPPASTCompositeTypeSpecifier getCompositeTypeSpecifier(IASTFunctionDefinition funcDef) { + if(funcDef != null) { + IBinding binding = funcDef.getDeclarator().getName().resolveBinding(); + if (binding instanceof CPPMethod) { + + CPPMethod methode = (CPPMethod) binding; + IASTNode decl = methode.getDeclarations()[0]; + + IASTNode spec = decl.getParent().getParent(); + if (spec instanceof ICPPASTCompositeTypeSpecifier) { + ICPPASTCompositeTypeSpecifier compTypeSpec = (ICPPASTCompositeTypeSpecifier) spec; + return compTypeSpec; + } + } + } + return null; + } + + private IASTFunctionDefinition getFunctionDefinition() { + IASTNode node = target; + while((node = node.getParent()) != null){ + if (node instanceof IASTFunctionDefinition) { + IASTFunctionDefinition funcDef = (IASTFunctionDefinition) node; + return funcDef; + } + } + return null; + } + + private void findAllNodesForReplacement(Collection literalExpressionVector) { + + + if (target.getParent() instanceof IASTUnaryExpression) { + IASTUnaryExpression unary = (IASTUnaryExpression) target.getParent(); + for (IASTLiteralExpression expression : literalExpressionVector) { + if( target.getKind() == expression.getKind() + && target.toString().equals( expression.toString() ) + && expression.getParent() instanceof IASTUnaryExpression + && unary.getOperator() == ((IASTUnaryExpression)expression.getParent()).getOperator()) { + literalsToReplace.add( ((IASTUnaryExpression)expression.getParent()) ); + } + } + } else { + for (IASTLiteralExpression expression : literalExpressionVector) { + if( target.getKind() == expression.getKind() + && target.toString().equals( expression.toString() ) ) { + literalsToReplace.add( expression ); + } + } + } + } + + private boolean isOneMarked(Collection literalExpressionVector, ITextSelection textSelection) { + boolean oneMarked = false; + for (IASTLiteralExpression expression : literalExpressionVector) { + boolean isInSameFileSelection = isInSameFileSelection(textSelection, expression); + if(isInSameFileSelection){ + if(target == null) { + target = expression; + oneMarked = true; + } else { + oneMarked = false; + } + } + } + return oneMarked; + } + + private Collection findAllLiterals() { + final Collection result = new ArrayList(); + + unit.accept(new CPPASTVisitor(){ + { + shouldVisitExpressions = true; + } + @Override + public int visit(IASTExpression expression) { + if (expression instanceof IASTLiteralExpression) { + if(!(expression.getNodeLocations().length == 1 + && expression.getNodeLocations()[0] instanceof IASTMacroExpansionLocation)){ + IASTLiteralExpression literal = (IASTLiteralExpression) expression; + result.add(literal); + } + } + return super.visit(expression); + } + + }); + + return result; + } + + @Override + protected void collectModifications(IProgressMonitor pm, ModificationCollector collector) + throws CoreException, OperationCanceledException { + + MethodContext context = findContext(target); + Collection locLiteralsToReplace = new ArrayList(); + + if(context.getType() == MethodContext.ContextType.METHOD){ + + for (IASTExpression expression : literalsToReplace) { + MethodContext exprContext = findContext(expression); + if(exprContext.getType() == MethodContext.ContextType.METHOD){ + if( MethodContext.isSameClass(exprContext.getMethodQName(), context.getMethodQName())){ + locLiteralsToReplace.add(expression); + } + } + } + + } else { + + for (IASTExpression expression : literalsToReplace) { + IPath path = new Path(expression.getContainingFilename()); + IFile expressionFile = ResourcesPlugin.getWorkspace().getRoot().getFileForLocation(path); + //expressionFile may be null if the file is NOT in the workspace + if( expressionFile != null && expressionFile.equals(file) ){ + locLiteralsToReplace.add(expression); + } + } + + } + + //Create all Changes for literals + String constName = info.getName(); + createLiteralToConstantChanges(constName, locLiteralsToReplace, collector); + + if(context.getType() == MethodContext.ContextType.METHOD) { + ICPPASTCompositeTypeSpecifier classDefinition = (ICPPASTCompositeTypeSpecifier) context.getMethodDeclaration().getParent(); + AddDeclarationNodeToClassChange.createChange(classDefinition, info.getVisibility(), getConstNodesClass(constName), true, collector); + } else { + IASTDeclaration nodes = getConstNodesGlobal(constName); + ASTRewrite rewriter = collector.rewriterForTranslationUnit(unit); + rewriter.insertBefore(unit, TranslationUnitHelper.getFirstNode(unit), nodes, new TextEditGroup(Messages.ExtractConstantRefactoring_CreateConstant)); + } + } + + private void createLiteralToConstantChanges(String constName, Iterable literals, ModificationCollector collector) { + + for (IASTExpression each : literals) { + ASTRewrite rewrite = collector.rewriterForTranslationUnit(each.getTranslationUnit()); + CPPASTIdExpression idExpression = new CPPASTIdExpression(new CPPASTName(constName.toCharArray())); + rewrite.replace(each, idExpression, new TextEditGroup(Messages.ExtractConstantRefactoring_ReplaceLiteral)); + } + } + + private IASTSimpleDeclaration getConstNodes(String newName){ + + ICPPASTSimpleDeclSpecifier declSpec = new CPPASTSimpleDeclSpecifier(); + declSpec.setConst(true); + + switch(target.getKind()){ + case IASTLiteralExpression.lk_char_constant: + declSpec.setType(IASTSimpleDeclSpecifier.t_char); + break; + case IASTLiteralExpression.lk_float_constant: + declSpec.setType(IASTSimpleDeclSpecifier.t_float); + break; + case IASTLiteralExpression.lk_integer_constant: + declSpec.setType(IASTSimpleDeclSpecifier.t_int); + break; + case IASTLiteralExpression.lk_string_literal: + declSpec.setType(ICPPASTSimpleDeclSpecifier.t_wchar_t); + break; + case ICPPASTLiteralExpression.lk_false: + //Like lk_true a boolean type + case ICPPASTLiteralExpression.lk_true: + declSpec.setType(ICPPASTSimpleDeclSpecifier.t_bool); + break; + case ICPPASTLiteralExpression.lk_this: + break; + } + + IASTSimpleDeclaration simple = new CPPASTSimpleDeclaration(); + simple.setDeclSpecifier(declSpec); + + IASTDeclarator decl = new CPPASTDeclarator(); + IASTName name = new CPPASTName(newName.toCharArray()); + decl.setName(name); + IASTInitializerExpression init = new CPPASTInitializerExpression(); + if (target.getParent() instanceof IASTUnaryExpression) { + IASTUnaryExpression unary = (IASTUnaryExpression) target.getParent(); + init.setExpression(unary); + } else { + CPPASTLiteralExpression expression = new CPPASTLiteralExpression(target.getKind(), target.toString()); + init.setExpression(expression); + } + decl.setInitializer(init); + simple.addDeclarator(decl); + + return simple; + } + + private IASTDeclaration getConstNodesGlobal(String newName){ + IASTSimpleDeclaration simple = getConstNodes(newName); + + if(unit.getParserLanguage().isCPP()){ + ICPPASTNamespaceDefinition namespace = new CPPASTNamespaceDefinition(); + namespace.setName(new CPPASTName()); + namespace.addDeclaration(simple); + return namespace; + } + + simple.getDeclSpecifier().setStorageClass(IASTDeclSpecifier.sc_static); + return simple; + } + + private IASTDeclaration getConstNodesClass(String newName){ + IASTSimpleDeclaration simple = getConstNodes(newName); + simple.getDeclSpecifier().setStorageClass(IASTDeclSpecifier.sc_static); + return simple; + } + +} diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/extractconstant/ExtractConstantRefactoringRunner.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/extractconstant/ExtractConstantRefactoringRunner.java new file mode 100644 index 00000000000..03ced89378c --- /dev/null +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/extractconstant/ExtractConstantRefactoringRunner.java @@ -0,0 +1,61 @@ +/******************************************************************************* + * Copyright (c) 2008 Institute for Software, HSR Hochschule fuer Technik + * Rapperswil, University of applied sciences and others + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Institute for Software - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.ui.refactoring.extractconstant; + +import org.eclipse.core.resources.IFile; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.ltk.ui.refactoring.RefactoringWizardOpenOperation; +import org.eclipse.ui.IWorkbenchWindow; + +import org.eclipse.cdt.ui.CUIPlugin; + +import org.eclipse.cdt.internal.ui.refactoring.CRefactoring; +import org.eclipse.cdt.internal.ui.refactoring.NameNVisibilityInformation; +import org.eclipse.cdt.internal.ui.refactoring.RefactoringRunner; + +/** + * @author Emanuel Graf + * + */ +public class ExtractConstantRefactoringRunner extends RefactoringRunner { + + public ExtractConstantRefactoringRunner(IFile file, ISelection selection, IWorkbenchWindow window) { + super(file, selection, window); + } + + + + + @Override + public void run() { + NameNVisibilityInformation info = new NameNVisibilityInformation(); + CRefactoring refactoring = new ExtractConstantRefactoring(file,selection,info); + ExtractConstantRefactoringWizard wizard = new ExtractConstantRefactoringWizard(refactoring, info); + RefactoringWizardOpenOperation operator = new RefactoringWizardOpenOperation(wizard); + + try { + refactoring.lockIndex(); + try { + operator.run(window.getShell(), refactoring.getName()); + } + finally { + refactoring.unlockIndex(); + } + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + } catch (CoreException e) { + CUIPlugin.getDefault().log(e); + } + } + +} diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/extractconstant/ExtractConstantRefactoringWizard.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/extractconstant/ExtractConstantRefactoringWizard.java new file mode 100644 index 00000000000..24b441072e8 --- /dev/null +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/extractconstant/ExtractConstantRefactoringWizard.java @@ -0,0 +1,37 @@ +/******************************************************************************* + * Copyright (c) 2008 Institute for Software, HSR Hochschule fuer Technik + * Rapperswil, University of applied sciences and others + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Institute for Software - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.ui.refactoring.extractconstant; + +import org.eclipse.ltk.core.refactoring.Refactoring; +import org.eclipse.ltk.ui.refactoring.RefactoringWizard; + +import org.eclipse.cdt.internal.ui.refactoring.NameNVisibilityInformation; +import org.eclipse.cdt.internal.ui.refactoring.dialogs.ExtractInputPage; + +public class ExtractConstantRefactoringWizard extends RefactoringWizard { + + private ExtractInputPage page; + private final NameNVisibilityInformation info; + + public ExtractConstantRefactoringWizard(Refactoring refactoring, NameNVisibilityInformation info) { + super(refactoring, WIZARD_BASED_USER_INTERFACE); + this.info = info; + } + + @Override + protected void addUserInputPages() { + page = new InputPage(Messages.ExtractConstantRefactoring_ExtractConst, info); + addPage(page); + + } + +} diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/extractconstant/InputPage.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/extractconstant/InputPage.java new file mode 100644 index 00000000000..e46aae3fae3 --- /dev/null +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/extractconstant/InputPage.java @@ -0,0 +1,39 @@ +/******************************************************************************* + * Copyright (c) 2008 Institute for Software, HSR Hochschule fuer Technik + * Rapperswil, University of applied sciences and others + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Institute for Software - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.ui.refactoring.extractconstant; + +import java.util.Vector; + +import org.eclipse.osgi.util.NLS; + +import org.eclipse.cdt.internal.ui.refactoring.NameNVisibilityInformation; +import org.eclipse.cdt.internal.ui.refactoring.dialogs.ExtractInputPage; + +public class InputPage extends ExtractInputPage { + + private final Vector usedNames; + + public InputPage(String name, NameNVisibilityInformation info) { + super(name, info); + label = Messages.InputPage_ConstName; + errorLabel = Messages.InputPage_EnterContName; + usedNames = info.getUsedNames(); + } + + @Override + protected void verifyName(String name) { + if(usedNames.contains(name)) { + setErrorMessage(NLS.bind(Messages.InputPage_NameAlreadyDefined, name)); + setPageComplete(false); + } + } +} diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/extractconstant/Messages.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/extractconstant/Messages.java new file mode 100644 index 00000000000..ac19408a21c --- /dev/null +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/extractconstant/Messages.java @@ -0,0 +1,37 @@ +/******************************************************************************* + * Copyright (c) 2008 Institute for Software, HSR Hochschule fuer Technik + * Rapperswil, University of applied sciences and others + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Institute for Software - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.ui.refactoring.extractconstant; + +import org.eclipse.osgi.util.NLS; + +public final class Messages extends NLS { + + private static final String BUNDLE_NAME = "org.eclipse.cdt.internal.ui.refactoring.extractconstant.messages";//$NON-NLS-1$ + + private Messages() { + // Do not instantiate + } + + public static String InputPage_ConstName; + public static String InputPage_EnterContName; + public static String InputPage_NameAlreadyDefined; + public static String ExtractConstantRefactoring_ExtractConst; + public static String ExtractConstantRefactoring_LiteralMustBeSelected; + public static String ExtractConstantRefactoring_NoLiteralSelected; + public static String ExtractConstantRefactoring_TooManyLiteralSelected; + public static String ExtractConstantRefactoring_CreateConstant; + public static String ExtractConstantRefactoring_ReplaceLiteral; + + static { + NLS.initializeMessages(BUNDLE_NAME, Messages.class); + } +} diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/extractconstant/messages.properties b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/extractconstant/messages.properties new file mode 100644 index 00000000000..63eec489920 --- /dev/null +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/extractconstant/messages.properties @@ -0,0 +1,21 @@ +############################################################################### +# Copyright (c) 2008 Institute for Software, HSR Hochschule fuer Technik +# Rapperswil, University of applied sciences and others +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Eclipse Public License v1.0 +# which accompanies this distribution, and is available at +# http://www.eclipse.org/legal/epl-v10.html +# +# Contributors: +# Institute for Software - initial API and implementation +############################################################################### +InputPage_ConstName=Constant &name: +InputPage_EnterContName=Enter a name for the new constant +InputPage_NameAlreadyDefined=An element named '{0}' is already defined in this scope. +ExtractConstantRefactoring_ExtractConst=Extract Constant +ExtractConstantRefactoring_LiteralMustBeSelected=An literal expression must be selected to activate this refactoring. +ExtractConstantRefactoring_NoLiteralSelected=No selected literal. +ExtractConstantRefactoring_TooManyLiteralSelected=Too many literals selected. +ExtractConstantRefactoring_CreateConstant=Create constant +ExtractConstantRefactoring_ReplaceLiteral=Replace a literal + diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/messages.properties b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/messages.properties new file mode 100644 index 00000000000..a0c1a59f1a8 --- /dev/null +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/messages.properties @@ -0,0 +1,29 @@ +############################################################################### +# Copyright (c) 2008 Institute for Software, HSR Hochschule fuer Technik +# Rapperswil, University of applied sciences and others +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Eclipse Public License v1.0 +# which accompanies this distribution, and is available at +# http://www.eclipse.org/legal/epl-v10.html +# +# Contributors: +# Institute for Software - initial API and implementation +############################################################################### +DeleteFileChange_0=Delete File +DeleteFileChange_1=File doesn't exist. +HSRRefactoring_name=HSR Refactoring +HSRRefactoring_PM_LoadTU=Load Translation Unit +HSRRefactoring_PM_CheckTU=Check Translation Unit +HSRRefactoring_PM_InitRef=Initialize Refactoring +HSRRefactoring_PM_ParseTU=Parse Translation Unit +HSRRefactoring_PM_MergeComments=Merge Comments +HSRRefactoring_CanceledByUser=Refactoring canceled by user. +HSRRefactoring_CompileErrorInTU=The Translation Unit contains one or several problems. This can be caused by a syntax error in the code or a parser flaw. The refactoring will possibly fail. +AddDeclarationNodeToClassChange_AddDeclaration=Add Declaration to Class {0}. +CreateFileChange_CreateFile=Create file: {0} +CreateFileChange_UnknownLoc=Unknown Location: {0} +CreateFileChange_FileExists=File already exists: {0} +HSRRefactoring_SelectionNotValid=Selection is not valid. +HSRRefactoring_CantLoadTU=Can not load translation unit. +HSRRefactoring_Ambiguity=Translation unit is ambiguous. +NO_FILE=File not found. diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/rename/ASTManager.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/rename/ASTManager.java new file mode 100644 index 00000000000..8bcdd891875 --- /dev/null +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/rename/ASTManager.java @@ -0,0 +1,1496 @@ +/******************************************************************************* + * Copyright (c) 2005, 2008 Wind River Systems, Inc. and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Markus Schorn - initial API and implementation + * IBM Corporation + ******************************************************************************/ +package org.eclipse.cdt.internal.ui.refactoring.rename; + +import java.text.MessageFormat; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.eclipse.core.resources.IFile; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.OperationCanceledException; +import org.eclipse.core.runtime.Path; +import org.eclipse.ltk.core.refactoring.RefactoringStatus; +import org.eclipse.ltk.core.refactoring.RefactoringStatusEntry; + +import org.eclipse.cdt.core.dom.ast.ASTVisitor; +import org.eclipse.cdt.core.dom.ast.DOMException; +import org.eclipse.cdt.core.dom.ast.IASTCompositeTypeSpecifier; +import org.eclipse.cdt.core.dom.ast.IASTDeclSpecifier; +import org.eclipse.cdt.core.dom.ast.IASTDeclaration; +import org.eclipse.cdt.core.dom.ast.IASTDeclarator; +import org.eclipse.cdt.core.dom.ast.IASTFileLocation; +import org.eclipse.cdt.core.dom.ast.IASTFunctionDefinition; +import org.eclipse.cdt.core.dom.ast.IASTFunctionStyleMacroParameter; +import org.eclipse.cdt.core.dom.ast.IASTName; +import org.eclipse.cdt.core.dom.ast.IASTNamedTypeSpecifier; +import org.eclipse.cdt.core.dom.ast.IASTNode; +import org.eclipse.cdt.core.dom.ast.IASTNodeLocation; +import org.eclipse.cdt.core.dom.ast.IASTPreprocessorFunctionStyleMacroDefinition; +import org.eclipse.cdt.core.dom.ast.IASTPreprocessorMacroDefinition; +import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration; +import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit; +import org.eclipse.cdt.core.dom.ast.IArrayType; +import org.eclipse.cdt.core.dom.ast.IBasicType; +import org.eclipse.cdt.core.dom.ast.IBinding; +import org.eclipse.cdt.core.dom.ast.ICompositeType; +import org.eclipse.cdt.core.dom.ast.IEnumeration; +import org.eclipse.cdt.core.dom.ast.IEnumerator; +import org.eclipse.cdt.core.dom.ast.IField; +import org.eclipse.cdt.core.dom.ast.IFunction; +import org.eclipse.cdt.core.dom.ast.IFunctionType; +import org.eclipse.cdt.core.dom.ast.IMacroBinding; +import org.eclipse.cdt.core.dom.ast.IParameter; +import org.eclipse.cdt.core.dom.ast.IPointerType; +import org.eclipse.cdt.core.dom.ast.IProblemBinding; +import org.eclipse.cdt.core.dom.ast.IQualifierType; +import org.eclipse.cdt.core.dom.ast.IScope; +import org.eclipse.cdt.core.dom.ast.IType; +import org.eclipse.cdt.core.dom.ast.ITypedef; +import org.eclipse.cdt.core.dom.ast.IVariable; +import org.eclipse.cdt.core.dom.ast.c.ICCompositeTypeScope; +import org.eclipse.cdt.core.dom.ast.c.ICFunctionPrototypeScope; +import org.eclipse.cdt.core.dom.ast.c.ICFunctionScope; +import org.eclipse.cdt.core.dom.ast.c.ICScope; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTDeclSpecifier; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTQualifiedName; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTranslationUnit; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPBase; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPBlockScope; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassScope; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPConstructor; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPField; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionScope; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespace; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespaceScope; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPReferenceType; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateTypeParameter; +import org.eclipse.cdt.core.index.IIndex; +import org.eclipse.cdt.core.model.CoreModel; +import org.eclipse.cdt.core.model.ICElement; +import org.eclipse.cdt.core.model.ITranslationUnit; +import org.eclipse.cdt.ui.CUIPlugin; + +import org.eclipse.cdt.internal.core.dom.SavedCodeReaderFactory; +import org.eclipse.cdt.internal.core.dom.parser.ASTInternal; +import org.eclipse.cdt.internal.core.dom.parser.c.CVisitor; +import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPImplicitMethod; +import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPMethod; +import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPVisitor; + + +/** + * Used per refactoring to cache the IASTTranslationUnits. Collects methods operating + * on ASTNodes. + */ +public class ASTManager { + public final static int TRUE= 1; + public final static int FALSE= 0; + public final static int UNKNOWN= -1; + + private Map fTranslationUnits= new HashMap(); + private HashSet fProblemUnits= new HashSet(); + private CRefactoringArgument fArgument; + private IBinding[] fValidBindings; + private String fRenameTo; + private HashMap fKnownBindings; + private HashSet fConflictingBinding; + + public static String nth_of_m(int n, int m) { + StringBuffer nofm= new StringBuffer(); + append_nth_of_m(n, m, nofm); + return nofm.toString(); + } + + static void append_nth_of_m(int n, int m, StringBuffer buf) { + buf.append(n); + switch(n) { + case 1: + buf.append("st"); //$NON-NLS-1$ + break; + case 2: + buf.append("nd"); //$NON-NLS-1$ + break; + case 3: + buf.append("rd"); //$NON-NLS-1$ + break; + default: + buf.append("th"); //$NON-NLS-1$ + break; + } + buf.append(" of "); //$NON-NLS-1$ + buf.append(m); + } + + public static IASTFileLocation getLocationInTranslationUnit(IASTNode node) { + return node.getFileLocation(); + } + + public static IASTName getSimpleName(IASTName name) { + if (name instanceof ICPPASTQualifiedName) { + IASTName names[]= ((ICPPASTQualifiedName) name).getNames(); + if (names.length > 0) { + name= names[names.length-1]; + } + } + return name; + } + + /** + * Returns TRUE, FALSE or UNKNOWN. + * @throws DOMException + */ + public static int isSameBinding(IBinding b1, IBinding b2) throws DOMException { + if (b1==null || b2==null) { + return UNKNOWN; + } + if (b1.equals(b2)) { + return TRUE; + } + String n1= b1.getName(); + String n2= b2.getName(); + if (n1==null || n2==null) { + return UNKNOWN; + } + if (!n1.equals(n2)) { + return FALSE; + } + if (b1 instanceof ICompositeType) { + if (!(b2 instanceof ICompositeType)) { + return FALSE; + } + ICompositeType c1= (ICompositeType) b1; + ICompositeType c2= (ICompositeType) b2; + if (c1.getKey() != c2.getKey()) { + return FALSE; + } + IScope s1= c1.getCompositeScope(); + if (s1 != null) s1= s1.getParent(); + IScope s2= c2.getCompositeScope(); + if (s2 != null) s2= s2.getParent(); + return isSameScope(s1, s2, false); + } + + if (b1 instanceof IFunction) { + if (!(b2 instanceof IFunction)) { + return FALSE; + } + boolean isStatic= false; + boolean checkSig= true; + IFunction c1= (IFunction) b1; + IFunction c2= (IFunction) b2; + if (b1 instanceof ICPPMethod) { + if (!(b2 instanceof ICPPMethod)) { + return FALSE; + } + } + else { + if (b2 instanceof ICPPMethod) { + return FALSE; + } + isStatic= c1.isStatic() || c2.isStatic(); + if (!(b1 instanceof ICPPFunction) && !(b2 instanceof ICPPFunction)) { + checkSig= false; + } + } + + int r1= isSameScope(b1.getScope(), b2.getScope(), isStatic); + if (r1 == FALSE) { + return FALSE; + } + + int r2= checkSig ? hasSameSignature(c1, c2) : TRUE; + if (r2 == FALSE) { + return FALSE; + } + if (r1!=r2) { + return UNKNOWN; + } + return r1; + } + + if (b1 instanceof IVariable) { + boolean fileStatic= false; + if (!(b2 instanceof IVariable)) { + return FALSE; + } + + IVariable c1= (IVariable) b1; + IVariable c2= (IVariable) b2; + if (b1 instanceof IField) { + if (!(b2 instanceof IField)) { + return FALSE; + } + } + else if (b1 instanceof IParameter) { + if (!(b2 instanceof IParameter)) { + return FALSE; + } + } + else { + if (b2 instanceof IField || b2 instanceof IParameter) { + return FALSE; + } + fileStatic= c1.isStatic() || c2.isStatic(); + } + int result= isSameScope(c1.getScope(), c2.getScope(), fileStatic); + return result == UNKNOWN ? TRUE : result; + } + + if (b1 instanceof IEnumerator) { + if (!(b2 instanceof IEnumerator)) { + return FALSE; + } + return isSameScope(b1.getScope(), b2.getScope(), false); + } + + if (b1 instanceof ITypedef) { + if (!(b2 instanceof ITypedef)) { + return FALSE; + } + return isSameScope(b1.getScope(), b2.getScope(), false); + } + + if (b1 instanceof IMacroBinding) { + if (!(b2 instanceof IMacroBinding)) { + return FALSE; + } + return TRUE; + } + if (b1 instanceof IEnumeration) { + if (!(b2 instanceof IEnumeration)) { + return FALSE; + } + return isSameScope(b1.getScope(), b2.getScope(), false); + } + int scopeCmp= isSameScope(b1.getScope(), b2.getScope(), false); + if (scopeCmp != TRUE) { + return scopeCmp; + } + + if (b1.getClass().equals(b2.getClass())) { + return TRUE; + } + return UNKNOWN; + } + + public static int isSameScope(IScope s1, IScope s2, boolean fileStatic) throws DOMException { + if (s1==s2) { + return TRUE; + } + IASTNode node1= ASTInternal.getPhysicalNodeOfScope(s1); + IASTNode node2= ASTInternal.getPhysicalNodeOfScope(s2); + + // forward declarations do not have parent scopes. + if (s1==null) { + if (!fileStatic && node2 instanceof IASTTranslationUnit) { + return TRUE; + } + return UNKNOWN; + } + if (s2==null) { + if (!fileStatic && node1 instanceof IASTTranslationUnit) { + return TRUE; + } + return UNKNOWN; + } + + if (s1.equals(s2)) { + return TRUE; + } + + + + if (node1 instanceof IASTTranslationUnit && + node2 instanceof IASTTranslationUnit) { + return hasSameLocation(node1, node2, fileStatic); + } + + String name1= getName(s1); + String name2= getName(s2); + + if (s1 instanceof ICPPBlockScope) { + if (s2 instanceof ICPPBlockScope) { + return hasSameLocation(node1, node2, fileStatic); + } + return FALSE; + } + if (s1 instanceof ICPPNamespaceScope) { + if (s2 instanceof ICPPNamespaceScope) { + ICPPNamespaceScope n1= (ICPPNamespaceScope) s1; + ICPPNamespaceScope n2= (ICPPNamespaceScope) s2; + int r1= hasSameLocation(node1, node2, fileStatic); + if (r1 == TRUE) { + return r1; + } + if (!name1.equals(name2)) { + return FALSE; + } + return isSameScope(n1.getParent(), n2.getParent(), fileStatic); + } + return FALSE; + } + + if (!name1.equals(name2)) { + return FALSE; + } + + // classes + if (s1 instanceof ICPPClassScope || s1 instanceof ICCompositeTypeScope) { + if (s2 instanceof ICPPClassScope || s2 instanceof ICCompositeTypeScope) { + return isSameScope(s1.getParent(), s2.getParent(), fileStatic); + } + return FALSE; + } + if (s1 instanceof ICPPFunctionScope) { + if (s2 instanceof ICPPFunctionScope) { + return hasSameLocation(node1, node2, true); + } + return FALSE; + } + if (s1 instanceof ICFunctionScope || s1 instanceof ICFunctionPrototypeScope + || s1 instanceof ICScope) { + if (s2 instanceof ICFunctionScope || s2 instanceof ICFunctionPrototypeScope + || s2 instanceof ICScope) { + return hasSameLocation(node1, node2, true); + } + return FALSE; + } + + return isSameScope(s1.getParent(), s2.getParent(), fileStatic); + } + + public static String getName(IScope s1) { + String name= null; + try { + name= getNameOrNull(ASTInternal.getPhysicalNodeOfScope(s1)); + } + catch (DOMException e) { + } + return name == null ? s1.toString() : name; + } + + public static int hasSameSignature(IFunction b1, IFunction b2) throws DOMException { + int r1= isSameParameterList(b1.getParameters(), b2.getParameters()); + if (r1 == FALSE) { + return FALSE; + } + if (b1 instanceof ICPPMethod) { + if (b2 instanceof ICPPMethod) { +// ICPPMethod m1= (ICPPMethod) b1; +// ICPPMethod m2= (ICPPMethod) b2; + // todo check for const, restrict + return r1; + } + else { + return FALSE; + } + } + return r1; + } + + public static int hasSameSignature(IFunctionType b1, IFunctionType b2) throws DOMException { + return isSameParameterList(b1.getParameterTypes(), b2.getParameterTypes()); + } + + private static int isSameParameterList(IType[] p1, + IType[] p2) throws DOMException { + if (p1==p2) { + return TRUE; + } + if (p1 == null || p2 == null) { + return UNKNOWN; + } + if (p1.length != p2.length) { + return FALSE; + } + int retval= TRUE; + for (int i = 0; i < p2.length; i++) { + switch (isSameType(p1[i], p2[i])) { + case FALSE: + return FALSE; + case UNKNOWN: + retval= UNKNOWN; + break; + } + } + + return retval; + } + + private static int isSameParameterList(IParameter[] p1, + IParameter[] p2) throws DOMException { + if (p1==p2) { + return TRUE; + } + if (p1 == null || p2 == null) { + return UNKNOWN; + } + if (p1.length != p2.length) { + return FALSE; + } + int retval= TRUE; + for (int i = 0; i < p2.length; i++) { + switch (isSameType(p1[i].getType(), p2[i].getType())) { + case FALSE: + return FALSE; + case UNKNOWN: + retval= UNKNOWN; + break; + } + } + + return retval; + } + + + private static int isSameType(IType t1, IType t2) throws DOMException { + if (t1 != null && t2 != null && t1.isSameType(t2)) { + return TRUE; + } + t1= getRealType(t1); + t2= getRealType(t2); + if (t1==t2) { + return TRUE; + } + if (t1 == null || t2 == null || t1 instanceof IProblemBinding || + t2 instanceof IProblemBinding) { + return UNKNOWN; + } + + if (t1 instanceof IArrayType) { + if (t2 instanceof IArrayType) { + IArrayType a1= (IArrayType) t1; + IArrayType a2= (IArrayType) t2; + return isSameType(a1.getType(), a2.getType()); + } + return FALSE; + } + + if (t1 instanceof IBasicType) { + if (t2 instanceof IBasicType) { + IBasicType a1= (IBasicType) t1; + IBasicType a2= (IBasicType) t2; + if (getBasicType(a1.getType()) != getBasicType(a2.getType())) { + return FALSE; + } + if (getSigned(a1) != getSigned(a2) || a1.isUnsigned() != a2.isUnsigned()) { + return FALSE; + } + if (a1.isLong() != a2.isLong() || a1.isShort() != a2.isShort()) { + return FALSE; + } + return TRUE; + } + return FALSE; + } + + if (t1 instanceof ICompositeType) { + if (t2 instanceof ICompositeType) { + ICompositeType a1= (ICompositeType) t1; + ICompositeType a2= (ICompositeType) t2; + if (a1.getKey() != a2.getKey()) { + return FALSE; + } + return isSameScope(a1.getCompositeScope(), a2.getCompositeScope(), false); + } + return FALSE; + } + + if (t1 instanceof ICPPReferenceType) { + if (t2 instanceof ICPPReferenceType) { + ICPPReferenceType a1= (ICPPReferenceType) t1; + ICPPReferenceType a2= (ICPPReferenceType) t2; + return isSameType(a1.getType(), a2.getType()); + } + return FALSE; + } + + if (t1 instanceof ICPPTemplateTypeParameter) { + if (t2 instanceof ICPPTemplateTypeParameter) { + return TRUE; + } + return FALSE; + } + + if (t1 instanceof IEnumeration) { + if (t2 instanceof IEnumeration) { + IEnumeration a1= (IEnumeration) t1; + IEnumeration a2= (IEnumeration) t2; + + return isSameScope(a1.getScope(), a2.getScope(), false); + } + return FALSE; + } + + if (t1 instanceof IFunctionType) { + if (t2 instanceof IFunctionType) { + IFunctionType a1= (IFunctionType) t1; + IFunctionType a2= (IFunctionType) t2; + return hasSameSignature(a1, a2); + } + return FALSE; + } + + if (t1 instanceof IPointerType) { + if (t2 instanceof IPointerType) { + IPointerType a1= (IPointerType) t1; + IPointerType a2= (IPointerType) t2; + if (a1.isConst() != a2.isConst() || a1.isVolatile() != a2.isVolatile()) { + return FALSE; + } + return isSameType(a1.getType(), a2.getType()); + } + return FALSE; + } + + if (t1 instanceof IQualifierType) { + if (t2 instanceof IQualifierType) { + IQualifierType a1= (IQualifierType) t1; + IQualifierType a2= (IQualifierType) t2; + if (a1.isConst() != a2.isConst() || a1.isVolatile() != a2.isVolatile()) { + return FALSE; + } + return isSameType(a1.getType(), a2.getType()); + } + return FALSE; + } + + return UNKNOWN; + } + + private static boolean getSigned(IBasicType a2) throws DOMException { + if (a2.isSigned()) { + return true; + } + if (a2.isUnsigned()) { + return false; + } + switch(a2.getType()) { + case IBasicType.t_int: + case IBasicType.t_unspecified: + return true; + } + return false; + } + + private static int getBasicType(int bc) { + if (bc== IBasicType.t_unspecified) { + bc= IBasicType.t_int; + } + return bc; + } + + private static IType getRealType(IType t) { + while(t instanceof ITypedef) { + try { + t= ((ITypedef) t).getType(); + } catch (DOMException e) { + } + } + return t; + } + + private static String getNameOrNull(IASTNode node) { + if (node instanceof IASTDeclarator) { + return getSimpleName(((IASTDeclarator) node).getName()).toString(); + } + if (node instanceof IASTNamedTypeSpecifier) { + return getSimpleName(((IASTNamedTypeSpecifier) node).getName()).toString(); + } + if (node instanceof IASTCompositeTypeSpecifier) { + return getSimpleName(((IASTCompositeTypeSpecifier) node).getName()).toString(); + } + if (node instanceof IASTTranslationUnit) { + return ((IASTTranslationUnit) node).getFilePath(); + } + return null; + } + + private static int hasSameLocation(IASTNode node1, IASTNode node2, boolean fileStatic) throws DOMException { + if (node1 == null || node2 == null) { + return UNKNOWN; + } + if (!fileStatic && node1 instanceof IASTTranslationUnit && + node2 instanceof IASTTranslationUnit) { + return TRUE; + } + + IASTFileLocation l1= node1.getNodeLocations()[0].asFileLocation(); + IASTFileLocation l2= node2.getNodeLocations()[0].asFileLocation(); + if (l1==null || l2==null) { + return UNKNOWN; + } + if (!l1.getFileName().equals(l2.getFileName())) { + return FALSE; + } + if (l1.getNodeOffset() != l2.getNodeOffset()) { + return FALSE; + } + if (l1.getNodeLength() != l2.getNodeLength()) { + return FALSE; + } + return TRUE; + } + + private static IScope getContainingScope(IASTName name) { + IASTTranslationUnit tu= name.getTranslationUnit(); + if (tu == null) { + return null; + } + if (tu instanceof ICPPASTTranslationUnit) { + return CPPVisitor.getContainingScope(name); + } + return CVisitor.getContainingScope(name); + } + + public static int isVirtualMethod(ICPPMethod method) throws DOMException { + IASTDeclaration decl= null; + if( method instanceof CPPMethod ) + decl = ((CPPMethod)method).getPrimaryDeclaration(); + else if( decl instanceof CPPImplicitMethod ) + decl = ((CPPImplicitMethod)method).getPrimaryDeclaration(); + + IASTDeclSpecifier spec= null; + if (decl instanceof IASTFunctionDefinition) { + IASTFunctionDefinition def = (IASTFunctionDefinition) decl; + spec= def.getDeclSpecifier(); + } + else if (decl instanceof IASTSimpleDeclaration) { + IASTSimpleDeclaration sdecl = (IASTSimpleDeclaration) decl; + spec= sdecl.getDeclSpecifier(); + } + if (spec instanceof ICPPASTDeclSpecifier) { + ICPPASTDeclSpecifier cppSpec = (ICPPASTDeclSpecifier) spec; + if (cppSpec.isVirtual()) { + return TRUE; + } + } + + IScope scope= method.getScope(); + if (scope instanceof ICPPClassScope) { + ICPPClassScope classScope = (ICPPClassScope) scope; + ICPPClassType classType= classScope.getClassType(); + ICPPBase[] bases= classType.getBases(); + for (int i = 0; i < bases.length; i++) { + ICPPBase base = bases[i]; + if( !(base.getBaseClass() instanceof ICPPClassType) ) + continue; + ICPPClassType baseType= (ICPPClassType) base.getBaseClass(); + if (baseType != null) { + IScope baseScope= baseType.getCompositeScope(); + if (baseScope != null) { + IBinding[] alternates= baseScope.find(method.getName()); + for (int j = 0; j < alternates.length; j++) { + IBinding binding = alternates[j]; + if (binding instanceof CPPMethod) { + CPPMethod alternateMethod = (CPPMethod) binding; + if (hasSameSignature(method, alternateMethod)!=FALSE) { + if (isVirtualMethod(alternateMethod)==TRUE) { + return TRUE; + } + } + } + } + } + } + } + } + return FALSE; + } + + public static boolean isLocalVariable(IVariable v, IScope scope) { + if (v instanceof IParameter) { + return false; + } + while (scope != null) { + if (scope instanceof ICPPFunctionScope || + scope instanceof ICPPBlockScope || + scope instanceof ICFunctionScope) { + return true; + } + try { + scope= scope.getParent(); + } catch (DOMException e) { + scope= null; + } + } + return false; + } + + public static boolean isLocalVariable(IVariable v) { + try { + return isLocalVariable(v, v.getScope()); + } catch (DOMException e) { + return false; + } + } + + public static IBinding[] findInScope(final IScope scope, String name, + boolean removeGlobalsWhenClassScope) throws DOMException { + IBinding[] result= null; + result = scope.find(name); + if (result == null || result.length==0) { + return result; + } + + // eliminate global bindings when looking up in a class type + if (removeGlobalsWhenClassScope && + (scope instanceof ICPPClassScope || + scope instanceof ICCompositeTypeScope)) { + int count= 0; + for (int i = 0; i < result.length; i++) { + IBinding binding = result[i]; + IScope bscope= binding.getScope(); + if (! (bscope instanceof ICPPClassScope || bscope instanceof ICCompositeTypeScope)) { + result[i]= null; + } + else { + count++; + } + } + if (count < result.length) { + IBinding[] copy= new IBinding[count]; + int i=0; + for (int j = 0; j < result.length; j++) { + IBinding b = result[j]; + if (b != null) { + copy[i++]= b; + } + } + result= copy; + } + } + + // try to find constructors + if (scope instanceof ICPPBlockScope) { + for (int i = 0; i < result.length; i++) { + IBinding binding = result[i]; + if (binding instanceof ICPPClassType) { + ICPPClassType classType= (ICPPClassType) binding; + if (classType.getKey() == ICPPClassType.k_class) { + IBinding[] cons= classType.getConstructors(); + if (cons.length > 0 && ! (cons[0] instanceof IProblemBinding)) { + result[i]= cons[0]; + } + } + } + } + } + + return result; + } + + + + public ASTManager(CRefactoringArgument arg) { + fArgument= arg; + } + + void analyzeArgument(IIndex index, IProgressMonitor pm, RefactoringStatus status) { + if (fArgument == null) { + return; + } + + if (fArgument.getArgumentKind() != CRefactory.ARGUMENT_UNKNOWN) { + return; + } + + if( fArgument.getSourceFile() == null ) + return; + + SavedCodeReaderFactory.getInstance().getCodeReaderCache().flush(); + + pm.beginTask(Messages.getString("ASTManager.task.analyze"), 2); //$NON-NLS-1$ + IASTTranslationUnit tu= getTranslationUnit(index, fArgument.getSourceFile(), true, status); + pm.worked(1); + if (tu != null) { + IASTName name= tu.getNodeSelector(tu.getFilePath()).findEnclosingName(fArgument.getOffset(), fArgument.getLength()); + if (name instanceof ICPPASTQualifiedName) { + IASTName[] na= ((ICPPASTQualifiedName) name).getNames(); + name= na[na.length-1]; + } + fArgument.setName(name); + IBinding binding= name.resolveBinding(); + if (binding != null) { + IScope scope= null; + try { + scope = binding.getScope(); + } catch (DOMException e) { + handleDOMException(tu, e, status); + } + fArgument.setBinding(name.getTranslationUnit(), binding, scope); + } + } + pm.worked(1); + pm.done(); + } + + private IASTTranslationUnit getTranslationUnit(IIndex index, IFile sourceFile, + boolean cacheit, RefactoringStatus status) { + IASTTranslationUnit ast= fTranslationUnits.get(sourceFile); + if (ast == null) { + ICElement celem= CoreModel.getDefault().create(sourceFile); + if (celem instanceof ITranslationUnit) { + ITranslationUnit tu= (ITranslationUnit) celem; + int options= ITranslationUnit.AST_CONFIGURE_USING_SOURCE_CONTEXT | + ITranslationUnit.AST_SKIP_INDEXED_HEADERS; + try { + ast= tu.getAST(index, options); + } catch (CoreException e) { + status.addError(e.getMessage()); + } + if (tu != null && cacheit) { + fTranslationUnits.put(sourceFile, ast); + } + } + } + return ast; + } + + public void analyzeTextMatches(IIndex index, ArrayList matches, IProgressMonitor monitor, + RefactoringStatus status) { + CRefactoringMatchStore store= new CRefactoringMatchStore(); + for (Iterator iter = matches.iterator(); iter.hasNext();) { + CRefactoringMatch match = (CRefactoringMatch) iter.next(); + store.addMatch(match); + } + + int count= store.getFileCount(); + String taskName= Messages.getString("ASTManager.task.generateAst"); //$NON-NLS-1$ + monitor.beginTask(taskName, 2*count); + monitor.setTaskName(taskName); + + List files= store.getFileList(); + int cc= 0; + long now= System.currentTimeMillis(); + long update= now; + for (IFile file : files) { + cc++; + if (store.contains(file)) { + if ((now=System.currentTimeMillis()) > update) { + String nofm= nth_of_m(cc, count); + String taskname= MessageFormat.format(Messages.getString("ASTManager.subtask.analyzing"), //$NON-NLS-1$ + new Object[] {nofm}); + monitor.subTask(taskname); + update= now+1000; + } + boolean doParse= false; + Collection fm= store.getMatchesForFile(file); + for (Iterator iterator = fm.iterator(); !doParse && iterator.hasNext();) { + CRefactoringMatch match = (CRefactoringMatch) iterator.next(); + switch (match.getLocation()) { + case CRefactory.OPTION_IN_COMMENT: + case CRefactory.OPTION_IN_INCLUDE_DIRECTIVE: + case CRefactory.OPTION_IN_STRING_LITERAL: + break; + default: + doParse= true; + } + } + + if (doParse) { + IASTTranslationUnit tu= getTranslationUnit(index, file, false, status); + monitor.worked(1); + analyzeTextMatchesOfTranslationUnit(tu, store, status); + if (status.hasFatalError()) { + return; + } + monitor.worked(1); + } + else { + monitor.worked(2); + } + if (monitor.isCanceled()) { + throw new OperationCanceledException(); + } + } + else { + monitor.worked(2); + } + } + monitor.done(); + } + + private void analyzeTextMatchesOfTranslationUnit(IASTTranslationUnit tu, + final CRefactoringMatchStore store, final RefactoringStatus status) { + fKnownBindings= new HashMap(); + fConflictingBinding= new HashSet(); + final Set paths= new HashSet(); + boolean renamesMacro= fArgument.getArgumentKind() == CRefactory.ARGUMENT_MACRO; + + analyzeMacroMatches(tu, store, paths, status); + if (status.hasFatalError()) return; + + if (renamesMacro) { + findConflictingBindingsWithNewName(tu, store, paths, status); + if (status.hasFatalError()) return; + } + + analyzeLanguageMatches(tu, store, paths, status); + if (status.hasFatalError()) return; + + for (Iterator iter = paths.iterator(); iter.hasNext();) { + IPath path = iter.next(); + if (path != null) { + store.removePath(path); + } + } + handleConflictingBindings(tu, status); + fKnownBindings= null; + fConflictingBinding= null; + } + + private void analyzeLanguageMatches(IASTTranslationUnit tu, + final CRefactoringMatchStore store, final Set paths, + final RefactoringStatus status) { + ASTNameVisitor nv = new ASTSpecificNameVisitor(fArgument.getName()) { + @Override + protected int visitName(IASTName name, boolean isDestructor) { + IPath path= analyzeAstMatch(name, store, isDestructor, status); + paths.add(path); + return ASTVisitor.PROCESS_CONTINUE; + } + }; + tu.accept(nv); + } + + private void analyzeMacroMatches(IASTTranslationUnit tu, + final CRefactoringMatchStore store, final Set pathsVisited, + final RefactoringStatus status) { + String lookfor= fArgument.getName(); + IASTPreprocessorMacroDefinition[] mdefs= tu.getMacroDefinitions(); + for (int i = 0; i < mdefs.length; i++) { + IASTPreprocessorMacroDefinition mdef = mdefs[i]; + IASTName macroName= mdef.getName(); + String macroNameStr= macroName.toString(); + if (fRenameTo.equals(macroNameStr)) { + status.addFatalError(MessageFormat.format( + Messages.getString("ASTManager.error.macro.name.conflict"), //$NON-NLS-1$ + new Object[] {fRenameTo})); + return; + } + else if (lookfor.equals(macroNameStr)) { + IPath path= analyzeAstMatch(macroName, store, false, status); + pathsVisited.add(path); + IBinding macroBinding= macroName.resolveBinding(); + if (macroBinding != null) { + IASTName[] refs= tu.getReferences(macroBinding); + for (int j = 0; j < refs.length; j++) { + path= analyzeAstMatch(refs[j], store, false, status); + pathsVisited.add(path); + } + } + } + if (mdef instanceof IASTPreprocessorFunctionStyleMacroDefinition) { + boolean nameIsPar= false; + IASTPreprocessorFunctionStyleMacroDefinition fm= (IASTPreprocessorFunctionStyleMacroDefinition) mdef; + IASTFunctionStyleMacroParameter[] pars= fm.getParameters(); + if (pars != null) { + for (int j = 0; !nameIsPar && j paths, + final RefactoringStatus status) { + ASTNameVisitor nv = new ASTSpecificNameVisitor(fRenameTo) { + @Override + protected int visitName(IASTName name, boolean isDestructor) { + IPath path= addConflictingBindingForName(status, name); + paths.add(path); + return ASTVisitor.PROCESS_CONTINUE; + } + }; + tu.accept(nv); + } + + protected IPath addConflictingBindingForName(final RefactoringStatus status, IASTName name) { + IASTNodeLocation[] locations= name.getNodeLocations(); + IPath path= null; + if (locations != null && locations.length==1) { + IASTNodeLocation loc= locations[0]; + IASTFileLocation floc= loc.asFileLocation(); + if (floc != null) { + path= new Path(floc.getFileName()); + if (path != null) { + IBinding binding= name.resolveBinding(); + if (binding instanceof IProblemBinding) { + handleProblemBinding(name.getTranslationUnit(), + (IProblemBinding) binding, status); + } + else if (binding != null) { + fConflictingBinding.add(binding); + } + } + } + } + return path; + } + + protected IPath analyzeAstMatch(IASTName name, CRefactoringMatchStore store, + boolean isDestructor, RefactoringStatus status) { + IPath path= null; + CRefactoringMatch match= null; + + IASTFileLocation loc = getImageFileLocation(name); + if (loc != null) { + path= new Path(loc.getFileName()); + match= store.findMatch(path, loc.getNodeOffset() + (isDestructor ? 1 : 0)); + if (match != null) { + analyzeAstTextMatchPair(match, name, status); + } + } + return path; + } + + static IASTFileLocation getImageFileLocation(IASTName name) { + return name.getImageLocation(); + } + + private void analyzeAstTextMatchPair(CRefactoringMatch match, IASTName name, + RefactoringStatus status) { + + IBinding binding= name.resolveBinding(); + int cmp= FALSE; + Integer cmpObj= fKnownBindings.get(binding); + if (cmpObj != null) { + cmp= cmpObj.intValue(); + } + else if (binding instanceof IProblemBinding) { + cmp= UNKNOWN; + handleProblemBinding(name.getTranslationUnit(), (IProblemBinding) binding, status); + } + else { + for (int i = 0; i < fValidBindings.length; i++) { + IBinding renameBinding = fValidBindings[i]; + try { + int cmp0= isSameBinding(binding, renameBinding); + if (cmp0 != FALSE) { + cmp= cmp0; + } + if (cmp0 == TRUE) { + break; + } + } + catch (DOMException e) { + handleDOMException(name.getTranslationUnit(), e, status); + cmp= UNKNOWN; + } + } + fKnownBindings.put(binding, new Integer(cmp)); + } + switch(cmp) { + case TRUE: + match.setASTInformation(CRefactoringMatch.AST_REFERENCE); + if (fRenameTo != null) { + IScope scope= getContainingScope(name); + if (scope != null) { + IBinding[] conflicting= null; + try { + conflicting= findInScope(scope, fRenameTo, true); + } catch (Exception e) { + CUIPlugin.getDefault().log(e); + } + if (conflicting != null && conflicting.length > 0) { + fConflictingBinding.addAll(Arrays.asList(conflicting)); + } + } + } + break; + case FALSE: + match.setASTInformation(CRefactoringMatch.AST_REFERENCE_OTHER); + break; + } + } + + public void handleDOMException(IASTTranslationUnit tu, final DOMException e, RefactoringStatus status) { + handleProblemBinding(tu, e.getProblem(), status); + } + + public void handleProblemBinding(IASTTranslationUnit tu, final IProblemBinding pb, RefactoringStatus status) { + if (tu != null) { + String fpath= tu.getFilePath(); + if (fProblemUnits.add(fpath)) { + String msg= pb.getMessage(); + if (msg != null && msg.length() > 0) { + msg= MessageFormat.format(Messages.getString("ASTManager.warning.parsingError.detailed"), new Object[]{msg}); //$NON-NLS-1$ + } + else { + msg= Messages.getString("ASTManager.warning.parsingError"); //$NON-NLS-1$ + } + int line= pb.getLineNumber(); + if (line >= 1) { + msg= MessageFormat.format( + Messages.getString("ASTManager.warning.parsingError.withFileAndLine"), //$NON-NLS-1$ + new Object[] {msg, fpath, new Integer(line)}); + } + else { + msg= MessageFormat.format( + Messages.getString("ASTManager.warning.parsingError.withFile"), //$NON-NLS-1$ + new Object[] {msg, fpath}); + } + status.addWarning(msg); + } + } + } + + @SuppressWarnings("unchecked") + protected void handleConflictingBindings(IASTTranslationUnit tu, + RefactoringStatus status) { + if (fConflictingBinding.isEmpty()) { + return; + } + + int argKind= fArgument.getArgumentKind(); + boolean isVarParEnumerator= false; + boolean isLocalVarPar= false; + boolean isFunction= false; + boolean isContainer = false; + boolean isMacro= false; + + switch(argKind) { + case CRefactory.ARGUMENT_LOCAL_VAR: + case CRefactory.ARGUMENT_PARAMETER: + isLocalVarPar= true; + case CRefactory.ARGUMENT_FILE_LOCAL_VAR: + case CRefactory.ARGUMENT_GLOBAL_VAR: + case CRefactory.ARGUMENT_FIELD: + case CRefactory.ARGUMENT_ENUMERATOR: + isVarParEnumerator= true; + break; + case CRefactory.ARGUMENT_FILE_LOCAL_FUNCTION: + case CRefactory.ARGUMENT_GLOBAL_FUNCTION: + case CRefactory.ARGUMENT_VIRTUAL_METHOD: + case CRefactory.ARGUMENT_NON_VIRTUAL_METHOD: + isFunction= true; + break; + case CRefactory.ARGUMENT_TYPE: + case CRefactory.ARGUMENT_CLASS_TYPE: + case CRefactory.ARGUMENT_NAMESPACE: + isContainer = true; + break; + case CRefactory.ARGUMENT_MACRO: + isMacro= true; + break; + case CRefactory.ARGUMENT_INCLUDE_DIRECTIVE: + break; + } + + Collection[] cflc= new Collection[] {new HashSet(), new ArrayList(), new ArrayList()}; + String[] errs= null; + if (isMacro) { + errs= new String[]{ + Messages.getString("CRenameLocalProcessor.error.conflict") //$NON-NLS-1$ + }; + cflc[0]= fConflictingBinding; + } + else { + errs= new String[]{ + Messages.getString("CRenameLocalProcessor.error.shadow"), //$NON-NLS-1$ + Messages.getString("CRenameLocalProcessor.error.redeclare"), //$NON-NLS-1$ + Messages.getString("CRenameLocalProcessor.error.isShadowed"), //$NON-NLS-1$ + Messages.getString("CRenameLocalProcessor.error.overloads")}; //$NON-NLS-1$ + classifyConflictingBindings(tu, (Set) cflc[0], (List)cflc[1], (List)cflc[2], status); + } + + for (int i = 0; i < 3; i++) { + Collection coll= cflc[i]; + for (Iterator iter = coll.iterator(); iter.hasNext();) { + boolean warn= false; + String msg= errs[i]; + IBinding conflict = (IBinding) iter.next(); + String what= null; + if (conflict instanceof IEnumerator) { + if (isVarParEnumerator || isFunction || isMacro) { + what= Messages.getString("CRenameLocalProcessor.enumerator"); //$NON-NLS-1$ + } + } + else if (conflict instanceof ICPPField) { + if (isVarParEnumerator || isFunction || isMacro) { + what= Messages.getString("CRenameLocalProcessor.field"); //$NON-NLS-1$ + } + } + else if (conflict instanceof IParameter) { + if (isVarParEnumerator || isFunction || isMacro) { + if (i==1 && argKind ==CRefactory.ARGUMENT_LOCAL_VAR) { + msg= errs[0]; + } + what= Messages.getString("CRenameLocalProcessor.parameter"); //$NON-NLS-1$ + } + } + else if (conflict instanceof IVariable) { + if (isVarParEnumerator || isFunction || isMacro) { + IVariable conflictingVar= (IVariable) conflict; + what= Messages.getString("CRenameLocalProcessor.globalVariable"); //$NON-NLS-1$ + if (ASTManager.isLocalVariable(conflictingVar)) { + if (i==1 && argKind==CRefactory.ARGUMENT_PARAMETER) { + msg= errs[2]; + } + what= Messages.getString("CRenameLocalProcessor.localVariable"); //$NON-NLS-1$ + } + else { + try { + if (conflictingVar.isStatic()) { + what= Messages.getString("CRenameProcessorDelegate.fileStaticVariable"); //$NON-NLS-1$ + } + } catch (DOMException e) { + } + } + } + } + else if (conflict instanceof ICPPConstructor) { + if (isVarParEnumerator || isFunction || isMacro) { + what= Messages.getString("CRenameLocalProcessor.constructor"); //$NON-NLS-1$ + } + } + else if (conflict instanceof ICPPMethod) { + if (isVarParEnumerator || isFunction || isMacro) { + if (i==1) { + IBinding r= fArgument.getBinding(); + if (r instanceof ICPPMethod) { + try { + if (ASTManager.hasSameSignature((ICPPMethod) r, + (ICPPMethod) conflict) == ASTManager.FALSE) { + msg= errs[3]; + warn= true; + } + } catch (DOMException e) { + } + } + } + what= Messages.getString("CRenameLocalProcessor.method"); //$NON-NLS-1$ + } + } + else if (conflict instanceof IFunction) { + if (isVarParEnumerator || isFunction || isMacro) { + boolean ignore= false; + if (isLocalVarPar) { + IASTName[] refs= + fArgument.getTranslationUnit().getReferences(conflict); + if (refs==null || refs.length==0) { + ignore= true; + } + } + if (!ignore) { + IFunction conflictingFunction= (IFunction) conflict; + if (i==1 && conflict instanceof ICPPFunction) { + IBinding r= fArgument.getBinding(); + if (r instanceof ICPPFunction) { + try { + if (ASTManager.hasSameSignature((ICPPFunction) r, + conflictingFunction) == ASTManager.FALSE) { + msg= errs[3]; + warn= true; + } + } catch (DOMException e) { + } + } + } + + boolean isStatic= false; + try { + isStatic= conflictingFunction.isStatic(); + } catch (DOMException e) { + } + if (isStatic) { + what= Messages.getString("CRenameProcessorDelegate.fileStaticFunction"); //$NON-NLS-1$ + } + else { + what= Messages.getString("CRenameProcessorDelegate.globalFunction"); //$NON-NLS-1$ + } + } + } + } + else if (conflict instanceof ICompositeType || + conflict instanceof IEnumeration || + conflict instanceof ITypedef) { + if (isContainer || isMacro) { + what= Messages.getString("CRenameProcessorDelegate.type"); //$NON-NLS-1$ + } + } + else if (conflict instanceof ICPPNamespace) { + if (isContainer || isMacro) { + what= Messages.getString("CRenameProcessorDelegate.namespace"); //$NON-NLS-1$ + if (argKind==CRefactory.ARGUMENT_NAMESPACE) { + warn= true; + } + } + } + if (what != null) { + String message = Messages.getString("CRenameLocalProcessor.error.message"); //$NON-NLS-1$ + String message1 = MessageFormat.format(Messages.getString("CRenameLocalProcessor.error.message1"), //$NON-NLS-1$ + new Object[]{msg}); + String message2 = MessageFormat.format(Messages.getString("CRenameLocalProcessor.error.message2"), //$NON-NLS-1$ + new Object[]{conflict.getName()}); + String message3 = MessageFormat.format(Messages.getString("CRenameLocalProcessor.error.message3"), //$NON-NLS-1$ + new Object[]{what}); + String space = " \n"; //$NON-NLS-1$ + String formatted = message + space + message1 + space + message2 + space + message3; + RefactoringStatusEntry[] entries= status.getEntries(); + for (int j = 0; (conflict.getName() != null || msg != null || what != null) + && j shadows, Collection redecl, Collection barriers, + RefactoringStatus status) { + // collect bindings on higher or equal level + String name= fArgument.getName(); + IBinding[] newBindingsAboverOrEqual= null; + IScope oldBindingsScope= null; + for (Iterator iter= fKnownBindings.entrySet().iterator(); iter.hasNext();) { + Map.Entry entry= (Map.Entry) iter.next(); + IBinding oldBinding= (IBinding) entry.getKey(); + Integer value= (Integer) entry.getValue(); + if (value.intValue() == TRUE && oldBinding.getName().equals(name)) { + try { + oldBindingsScope = oldBinding.getScope(); + if (oldBindingsScope != null) { + newBindingsAboverOrEqual = ASTManager.findInScope(oldBindingsScope, fRenameTo, false); + } + } catch (DOMException e) { + handleDOMException(tu, e, status); + } + } + + if (newBindingsAboverOrEqual!=null && newBindingsAboverOrEqual.length>0) { + break; + } + } + if (newBindingsAboverOrEqual == null) { + newBindingsAboverOrEqual= new IBinding[0]; + } + + // check conflicting bindings for being from above or equal level. + for (Iterator iter = fConflictingBinding.iterator(); iter.hasNext();) { + IBinding conflictingBinding= iter.next(); + if (conflictingBinding != null) { + boolean isAboveOrEqual= false; + for (int i = 0; !isAboveOrEqual && i0) { + if (checkLocation(name)) { + return visitName(names[names.length-1]); + } + } + } + else if (checkLocation(name)) { + return visitName(name); + } + return PROCESS_CONTINUE; + } + + private boolean checkLocation(IASTNode node) { + if (fFileName==null) { + return true; + } + if (!fFileName.equals(node.getContainingFilename())) { + return false; + } + IASTFileLocation loc= null; + if (node instanceof IASTName) { + loc= ASTManager.getImageFileLocation((IASTName) node); + } + else { + IASTNodeLocation[] locs= node.getNodeLocations(); + if (locs!=null && locs.length==1) { + if (locs[0] instanceof IASTFileLocation) { + loc= (IASTFileLocation) locs[0]; + } + } + } + if (loc==null) { + return false; + } + if (fOffset==-1) { + return true; + } + int off= loc.getNodeOffset(); + int len = loc.getNodeLength(); + return off <= fOffset && fOffset < off+len; + } +} diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/rename/ASTSpecificNameVisitor.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/rename/ASTSpecificNameVisitor.java new file mode 100644 index 00000000000..fca955cfebb --- /dev/null +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/rename/ASTSpecificNameVisitor.java @@ -0,0 +1,45 @@ +/******************************************************************************* + * Copyright (c) 2004-2005 Wind River Systems, Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Markus Schorn - initial API and implementation + ******************************************************************************/ + +package org.eclipse.cdt.internal.ui.refactoring.rename; + +import org.eclipse.cdt.core.dom.ast.ASTVisitor; +import org.eclipse.cdt.core.dom.ast.IASTName; + +public abstract class ASTSpecificNameVisitor extends ASTNameVisitor { + private String fSearchForName; + + public ASTSpecificNameVisitor(String name) { + super(null); + fSearchForName= name; + } + + final public int visitName(IASTName name) { + String nameStr= name.toString(); + if (nameStr != null) { + final int len= nameStr.length(); + final int searchForLen= fSearchForName.length(); + if (len == searchForLen) { + if (nameStr.equals(fSearchForName)) { + return visitName(name, false); + } + } + else if (len == searchForLen+1) { + if (nameStr.charAt(0) == '~' && nameStr.endsWith(fSearchForName)) { + return visitName(name, true); + } + } + } + return ASTVisitor.PROCESS_CONTINUE; + } + + protected abstract int visitName(IASTName name, boolean isDestructor); +} diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/rename/CRefactoringArgument.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/rename/CRefactoringArgument.java new file mode 100644 index 00000000000..3df2018882b --- /dev/null +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/rename/CRefactoringArgument.java @@ -0,0 +1,191 @@ +/******************************************************************************* + * Copyright (c) 2004, 2008 Wind River Systems, Inc. and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Markus Schorn - initial API and implementation + ******************************************************************************/ +package org.eclipse.cdt.internal.ui.refactoring.rename; + +import org.eclipse.core.resources.IFile; + +import org.eclipse.cdt.core.CCorePlugin; +import org.eclipse.cdt.core.dom.ast.DOMException; +import org.eclipse.cdt.core.dom.ast.IASTName; +import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit; +import org.eclipse.cdt.core.dom.ast.IBinding; +import org.eclipse.cdt.core.dom.ast.ICompositeType; +import org.eclipse.cdt.core.dom.ast.IEnumeration; +import org.eclipse.cdt.core.dom.ast.IEnumerator; +import org.eclipse.cdt.core.dom.ast.IField; +import org.eclipse.cdt.core.dom.ast.IFunction; +import org.eclipse.cdt.core.dom.ast.IMacroBinding; +import org.eclipse.cdt.core.dom.ast.IParameter; +import org.eclipse.cdt.core.dom.ast.IScope; +import org.eclipse.cdt.core.dom.ast.ITypedef; +import org.eclipse.cdt.core.dom.ast.IVariable; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespace; +import org.eclipse.cdt.core.model.CModelException; +import org.eclipse.cdt.core.model.ICElement; +import org.eclipse.cdt.core.model.ISourceRange; +import org.eclipse.cdt.core.model.ISourceReference; + + +/** + * Represents the input to a refactoring. Important is file and offset the rest + * can be calculated from the AST. + */ +public class CRefactoringArgument { + private int fOffset=0; + private int fLength= 0; + private String fText= ""; //$NON-NLS-1$ + private int fKind= CRefactory.ARGUMENT_UNKNOWN; + private IFile fFile; + + private IBinding fBinding; + private IScope fScope; + private IASTTranslationUnit fTranslationUnit; + + public CRefactoringArgument(IFile file, int offset, int length) { + fKind= CRefactory.ARGUMENT_UNKNOWN; + fFile= file; + fOffset= offset; + fLength= length; + } + + public CRefactoringArgument(ICElement elem) { + fKind= CRefactory.ARGUMENT_UNKNOWN; + if (elem instanceof ISourceReference) { + ISourceReference sref= (ISourceReference) elem; + ISourceRange sr; + try { + sr = sref.getSourceRange(); + fFile= (IFile) sref.getTranslationUnit().getResource(); + fOffset= sr.getIdStartPos(); + fLength= sr.getIdLength(); + } catch (CModelException e) { + CCorePlugin.log(e); + } + } + } + + // overrider + public String getName() { + return fText; + } + + // overrider + public IFile getSourceFile() { + return fFile; + } + + // overrider + public int getArgumentKind() { + return fKind; + } + + // overrider + public int getOffset() { + return fOffset; + } + + public int getLength() { + return fLength; + } + + public void setName(IASTName name) { + fText= name.toString(); + } + + public void setBinding(IASTTranslationUnit tu, IBinding binding, IScope scope) { + fTranslationUnit= tu; + fBinding= binding; + fScope= scope; + if (binding instanceof IVariable) { + IVariable var= (IVariable) binding; + if (binding instanceof IField) { + fKind= CRefactory.ARGUMENT_FIELD; + } + else if (binding instanceof IParameter) { + fKind= CRefactory.ARGUMENT_PARAMETER; + } + else { + if (ASTManager.isLocalVariable(var, scope)) { + fKind= CRefactory.ARGUMENT_LOCAL_VAR; + } + else { + boolean isStatic= false; + try { + isStatic= var.isStatic(); + } catch (DOMException e) { + } + if (isStatic) { + fKind= CRefactory.ARGUMENT_FILE_LOCAL_VAR; + } + else { + fKind= CRefactory.ARGUMENT_GLOBAL_VAR; + } + } + } + } + else if (binding instanceof IEnumerator) { + fKind= CRefactory.ARGUMENT_ENUMERATOR; + } + else if (binding instanceof IFunction) { + fKind= CRefactory.ARGUMENT_NON_VIRTUAL_METHOD; + IFunction func= (IFunction) binding; + if (binding instanceof ICPPMethod) { + ICPPMethod method= (ICPPMethod) binding; + int isVirtual= ASTManager.UNKNOWN; + try { + isVirtual = ASTManager.isVirtualMethod(method); + } catch (DOMException e) { + } + if (isVirtual == ASTManager.TRUE) { + fKind= CRefactory.ARGUMENT_VIRTUAL_METHOD; + } + } + else { + boolean isStatic= false; + try { + isStatic= func.isStatic(); + } catch (DOMException e) { + } + if (isStatic) { + fKind= CRefactory.ARGUMENT_FILE_LOCAL_FUNCTION; + } + else { + fKind= CRefactory.ARGUMENT_GLOBAL_FUNCTION; + } + } + } + else if (binding instanceof ICompositeType) { + fKind= CRefactory.ARGUMENT_CLASS_TYPE; + } + else if (binding instanceof IEnumeration || binding instanceof ITypedef) { + fKind= CRefactory.ARGUMENT_TYPE; + } + else if (binding instanceof ICPPNamespace) { + fKind= CRefactory.ARGUMENT_NAMESPACE; + } + else if (binding instanceof IMacroBinding) { + fKind= CRefactory.ARGUMENT_MACRO; + } + } + + public IScope getScope() { + return fScope; + } + + public IBinding getBinding() { + return fBinding; + } + + public IASTTranslationUnit getTranslationUnit() { + return fTranslationUnit; + } +} diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/rename/CRefactoringMatch.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/rename/CRefactoringMatch.java new file mode 100644 index 00000000000..881fc661d1d --- /dev/null +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/rename/CRefactoringMatch.java @@ -0,0 +1,92 @@ +/******************************************************************************* + * Copyright (c) 2004, 2008 Wind River Systems, Inc. and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Markus Schorn - initial API and implementation + ******************************************************************************/ +package org.eclipse.cdt.internal.ui.refactoring.rename; + +import org.eclipse.core.resources.IFile; + +/** + * A refactoring match initially is a plain text match. In the course of refactoring + * it will be classified with a location (comment, code, ...) and with the information + * whether it has been verified via AST or not. + */ +public class CRefactoringMatch { + public static final int POTENTIAL= 0; + public static final int AST_REFERENCE= 1; + public static final int AST_REFERENCE_OTHER= 2; + public static final int AST_REFEREENCE_CONFLICTING= 3; + public static final int IN_COMMENT = 4; + + private static String[] LABELS= { + Messages.getString("CRefactoringMatch.label.potentialOccurrence"), //$NON-NLS-1$ + Messages.getString("CRefactoringMatch.label.occurrence"), //$NON-NLS-1$ + "", //$NON-NLS-1$ + Messages.getString("CRefactoringMatch.label.potentialOccurrence"), //$NON-NLS-1$ + Messages.getString("CRefactoringMatch.label.comment")}; //$NON-NLS-1$ + + private IFile fFile; + private int fOffset; + private int fLength; + private int fLocation; + private int fAstInformation= 0; + + public int getAstInformation() { + return fAstInformation; + } + + public CRefactoringMatch(IFile file, int offset, int length, int location) { + fFile= file; + fOffset= offset; + fLength= length; + fLocation= location; + } + public int getOffset() { + return fOffset; + } + public void setLocation(int location) { + fLocation= location; + } + public int getLocation() { + return fLocation; + } + public int getLength() { + return fLength; + } + public IFile getFile() { + return fFile; + } + public void setASTInformation(int val) { + switch(fAstInformation) { + case AST_REFERENCE: + case AST_REFERENCE_OTHER: + case AST_REFEREENCE_CONFLICTING: + if (val != fAstInformation) { + fAstInformation= AST_REFEREENCE_CONFLICTING; + } + break; + default: + fAstInformation= val; + break; + } + } + public String getLabel() { + if (fAstInformation == AST_REFERENCE) { + return LABELS[AST_REFERENCE]; + } + if (isInComment()) { + return LABELS[IN_COMMENT]; + } + return LABELS[POTENTIAL]; + } + + public boolean isInComment() { + return (fLocation & CRefactory.OPTION_IN_COMMENT) != 0; + } +} diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/rename/CRefactoringMatchStore.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/rename/CRefactoringMatchStore.java new file mode 100644 index 00000000000..fdbe50748b3 --- /dev/null +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/rename/CRefactoringMatchStore.java @@ -0,0 +1,123 @@ +/******************************************************************************* + * Copyright (c) 2004, 2008 Wind River Systems, Inc. and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Markus Schorn - initial API and implementation + ******************************************************************************/ +package org.eclipse.cdt.internal.ui.refactoring.rename; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.Comparator; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.SortedMap; +import java.util.TreeMap; + +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.Path; + + +public class CRefactoringMatchStore { + private Map fFileToPathMap= new HashMap(); + private Map> fPathToMatches= new HashMap>(); + private Comparator fOffsetComparator; + + public CRefactoringMatchStore() { + fOffsetComparator= new Comparator() { + public int compare(CRefactoringMatch o1, CRefactoringMatch o2) { + return o1.getOffset() - o2.getOffset(); + } + }; + } + + public void addMatch(CRefactoringMatch match) { + IPath path= resolvePath(match.getFile()); + if (path != null) { + Map matchesForPath= getMapForPath(path, true); + matchesForPath.put(match, match); + } + } + + private Map getMapForPath(IPath path, boolean create) { + SortedMap map= fPathToMatches.get(path); + if (map == null && create) { + map= new TreeMap(fOffsetComparator); + fPathToMatches.put(path, map); + } + return map; + } + + private IPath resolvePath(IFile file) { + IPath path= fFileToPathMap.get(file); + if (path == null) { + path= file.getLocation(); + if (path == null) { + path= file.getFullPath(); + } + fFileToPathMap.put(file, path); + } + return path; + } + + public int getFileCount() { + return fFileToPathMap.size(); + } + + public List getFileList() { + return new ArrayList(fFileToPathMap.keySet()); + } + + public boolean contains(IResource file) { + return fFileToPathMap.containsKey(file); + } + + public Collection getMatchesForFile(IResource file) { + return getMatchesForPath(fFileToPathMap.get(file)); + } + + public Collection getMatchesForPath(IPath path) { + if (path != null) { + Map map= fPathToMatches.get(path); + if (map != null) { + return map.keySet(); + } + } + return Collections.emptySet(); + } + + public CRefactoringMatch findMatch(IPath path, int nodeOffset) { + Map map= fPathToMatches.get(path); + if (map != null) { + return (CRefactoringMatch) map.get(new CRefactoringMatch(null, nodeOffset, 0, 0)); + } + return null; + } + + public void removePath(IPath path) { + Map map= fPathToMatches.remove(path); + if (map != null && !map.isEmpty()) { + IFile file= ((CRefactoringMatch) map.values().iterator().next()).getFile(); + fFileToPathMap.remove(file); + } + } + + public Collection findMatchesInRange(Path path, int offset, int end) { + if (path != null) { + SortedMap map= fPathToMatches.get(path); + if (map != null) { + return map.subMap(new CRefactoringMatch(null, offset, 0, 0), + new CRefactoringMatch(null, end, 0, 0)).keySet(); + } + } + return Collections.emptySet(); + } +} diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/rename/CRefactoringUtils.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/rename/CRefactoringUtils.java new file mode 100644 index 00000000000..a6089642bed --- /dev/null +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/rename/CRefactoringUtils.java @@ -0,0 +1,40 @@ +/******************************************************************************* + * Copyright (c) 2005, 2008 Wind River Systems, Inc. and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Markus Schorn - initial API and implementation + ******************************************************************************/ +package org.eclipse.cdt.internal.ui.refactoring.rename; + +/** + * Collects some basic functionality. + */ +public class CRefactoringUtils { + + public static boolean isIdentifierChar(char c) { + return isLeadingIdentifierChar(c) || ('0'<=c && c<='9'); + } + + public static boolean isLeadingIdentifierChar(char c) { + return ('A'<=c && c<='Z') || ('a'<=c && c<='z') || c=='_'; + } + + public static boolean checkIdentifier(String id) { + if (id.length() == 0) { + return false; + } + if (!isLeadingIdentifierChar(id.charAt(0))) { + return false; + } + for (int i= 1; i < id.length(); i++) { + if (!isIdentifierChar(id.charAt(i))) { + return false; + } + } + return true; + } +} diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/rename/CRefactory.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/rename/CRefactory.java new file mode 100644 index 00000000000..da1d8fee30c --- /dev/null +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/rename/CRefactory.java @@ -0,0 +1,161 @@ +/******************************************************************************* + * Copyright (c) 2004, 2008 Wind River Systems, Inc. and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Markus Schorn - initial API and implementation + ******************************************************************************/ + +package org.eclipse.cdt.internal.ui.refactoring.rename; + +import java.util.Arrays; +import java.util.HashSet; +import java.util.Iterator; + +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.resources.ResourcesPlugin; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.Platform; +import org.eclipse.core.runtime.content.IContentType; +import org.eclipse.jface.text.ITextSelection; +import org.eclipse.ltk.ui.refactoring.RefactoringWizardOpenOperation; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.ui.ide.IDE; + +import org.eclipse.cdt.core.CCorePlugin; +import org.eclipse.cdt.core.model.ICElement; +import org.eclipse.cdt.core.model.IWorkingCopy; + + +/** + * Serves to launch the various refactorings. + */ +public class CRefactory { + public static final int OPTION_ASK_SCOPE = 0x01; + public static final int OPTION_IN_COMMENT = 0x02; + public static final int OPTION_IN_STRING_LITERAL = 0x04; + public static final int OPTION_IN_INCLUDE_DIRECTIVE = 0x08; + public static final int OPTION_IN_MACRO_DEFINITION = 0x10; + public static final int OPTION_IN_PREPROCESSOR_DIRECTIVE = 0x20; + public static final int OPTION_IN_INACTIVE_CODE = 0x40; + public static final int OPTION_IN_CODE = 0x80; + + public static final int ARGUMENT_UNKNOWN = 0; + public static final int ARGUMENT_LOCAL_VAR = 1; + public static final int ARGUMENT_PARAMETER = 2; + public static final int ARGUMENT_FILE_LOCAL_VAR = 3; + public static final int ARGUMENT_GLOBAL_VAR = 4; + public static final int ARGUMENT_FIELD = 5; + public static final int ARGUMENT_FILE_LOCAL_FUNCTION = 6; + public static final int ARGUMENT_GLOBAL_FUNCTION = 7; + public static final int ARGUMENT_VIRTUAL_METHOD = 8; + public static final int ARGUMENT_NON_VIRTUAL_METHOD = 9; + public static final int ARGUMENT_TYPE = 10; + public static final int ARGUMENT_MACRO = 11; + public static final int ARGUMENT_INCLUDE_DIRECTIVE = 12; + public static final int ARGUMENT_ENUMERATOR = 13; + public static final int ARGUMENT_CLASS_TYPE = 14; + public static final int ARGUMENT_NAMESPACE = 15; + + private static CRefactory sInstance= new CRefactory(); + private TextSearchWrapper fTextSearch; + + public static CRefactory getInstance() { + return sInstance; + } + + private CRefactory() { + } + + // runs the rename refactoring + public void rename(Shell shell, ICElement arg) { + if (!IDE.saveAllEditors( + new IResource[] {ResourcesPlugin.getWorkspace().getRoot()}, + false)) { + return; + } + CRefactoringArgument iarg= new CRefactoringArgument(arg); + final CRenameProcessor processor = new CRenameProcessor(this, iarg); + try { + processor.lockIndex(); + try { + CRenameRefactoring r= new CRenameRefactoring(processor); + RefactoringWizardOpenOperation op= + new RefactoringWizardOpenOperation(new CRenameRefactoringWizard(r)); + op.run(shell, Messages.getString("CRefactory.title.rename")); //$NON-NLS-1$ + } + finally { + processor.unlockIndex(); + } + } catch (CoreException e) { + CCorePlugin.log(e); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + } + } + + public void rename(Shell shell, IWorkingCopy wc, ITextSelection s) { + IResource res= wc.getResource(); + if (res instanceof IFile == false) { + return; + } + if (!IDE.saveAllEditors( + new IResource[] {ResourcesPlugin.getWorkspace().getRoot()}, + false)) { + return; + } + CRefactoringArgument iarg= new CRefactoringArgument((IFile) res, s.getOffset(), s.getLength()); + CRenameRefactoring r= new CRenameRefactoring(new CRenameProcessor(this, iarg)); + RefactoringWizardOpenOperation op= + new RefactoringWizardOpenOperation(new CRenameRefactoringWizard(r)); + try { + op.run(shell, Messages.getString("CRefactory.title.rename")); //$NON-NLS-1$ + } catch (InterruptedException e) { + // operation was canceled + } + } + + + public TextSearchWrapper getTextSearch() { + if (fTextSearch == null) { + return new TextSearchWrapper(); + } + return fTextSearch; + } + + public String[] getCCppPatterns() { + IContentType[] cts= Platform.getContentTypeManager().getAllContentTypes(); + HashSet all= new HashSet(); + for (int i= 0; i < cts.length; i++) { + IContentType type= cts[i]; + boolean useit= false; + while (!useit && type != null) { + String id= type.getId(); + if (id.equals(CCorePlugin.CONTENT_TYPE_CHEADER) || + id.equals(CCorePlugin.CONTENT_TYPE_CSOURCE) || + id.equals(CCorePlugin.CONTENT_TYPE_CXXHEADER) || + id.equals(CCorePlugin.CONTENT_TYPE_CXXSOURCE)) { + useit= true; + } + else { + type= type.getBaseType(); + } + } + if (useit) { + String exts[] = + type.getFileSpecs(IContentType.FILE_EXTENSION_SPEC); + all.addAll(Arrays.asList(exts)); + } + } + String[] result= new String[all.size()]; + Iterator it= all.iterator(); + for (int i= 0; i < result.length; i++) { + result[i]= "*." + (String) it.next(); //$NON-NLS-1$ + } + return result; + } +} diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/rename/CRenameClassProcessor.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/rename/CRenameClassProcessor.java new file mode 100644 index 00000000000..fb3b3f6df16 --- /dev/null +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/rename/CRenameClassProcessor.java @@ -0,0 +1,63 @@ +/******************************************************************************* + * Copyright (c) 2005, 2008 Wind River Systems, Inc. and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Markus Schorn - initial API and implementation + ******************************************************************************/ +package org.eclipse.cdt.internal.ui.refactoring.rename; + +import java.util.ArrayList; +import java.util.Arrays; + +import org.eclipse.ltk.core.refactoring.RefactoringStatus; + +import org.eclipse.cdt.core.dom.ast.DOMException; +import org.eclipse.cdt.core.dom.ast.IBinding; +import org.eclipse.cdt.core.dom.ast.IScope; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPConstructor; + + +/** + * Processor adding constructor and destructor to the bindings to be renamed. + */ +public class CRenameClassProcessor extends CRenameTypeProcessor { + + public CRenameClassProcessor(CRenameProcessor processor, String kind) { + super(processor, kind); + } + + @Override + protected IBinding[] getBindingsToBeRenamed(RefactoringStatus status) { + CRefactoringArgument argument= getArgument(); + IBinding binding= argument.getBinding(); + ArrayList bindings= new ArrayList(); + if (binding != null) { + bindings.add(binding); + } + if (binding instanceof ICPPClassType) { + ICPPClassType ctype= (ICPPClassType) binding; + try { + ICPPConstructor[] ctors= ctype.getConstructors(); + if (ctors != null) { + bindings.addAll(Arrays.asList(ctors)); + } + + IScope scope= ctype.getCompositeScope(); + if (scope != null) { + IBinding[] dtors= scope.find("~" + argument.getName()); //$NON-NLS-1$ + if (dtors != null) { + bindings.addAll(Arrays.asList(dtors)); + } + } + } catch (DOMException e) { + getAstManager().handleDOMException(argument.getTranslationUnit(), e, status); + } + } + return bindings.toArray(new IBinding[bindings.size()]); + } +} diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/rename/CRenameGlobalProcessor.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/rename/CRenameGlobalProcessor.java new file mode 100644 index 00000000000..b5bb7c60ac8 --- /dev/null +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/rename/CRenameGlobalProcessor.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * Copyright (c) 2005, 2008 Wind River Systems, Inc. and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Markus Schorn - initial API and implementation + ******************************************************************************/ +package org.eclipse.cdt.internal.ui.refactoring.rename; + + +/** + * Rename processor that sets up the input page for renaming a global entity. + */ +public class CRenameGlobalProcessor extends CRenameProcessorDelegate { + + public CRenameGlobalProcessor(CRenameProcessor processor, String name) { + super(processor, name); + setAvailableOptions(CRefactory.OPTION_ASK_SCOPE | + CRefactory.OPTION_IN_CODE | + CRefactory.OPTION_IN_COMMENT | + CRefactory.OPTION_IN_MACRO_DEFINITION); + } +} diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/rename/CRenameIncludeProcessor.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/rename/CRenameIncludeProcessor.java new file mode 100644 index 00000000000..e05c2dddca9 --- /dev/null +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/rename/CRenameIncludeProcessor.java @@ -0,0 +1,32 @@ +/******************************************************************************* + * Copyright (c) 2004,2008 Wind River Systems, Inc. and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Markus Schorn - initial API and implementation + ******************************************************************************/ +package org.eclipse.cdt.internal.ui.refactoring.rename; + +/** + * Rename processor setting up input page for renaming include directives. + */ +public class CRenameIncludeProcessor extends CRenameProcessorDelegate { + + public CRenameIncludeProcessor(CRenameProcessor input, String kind) { + super(input, kind); + setAvailableOptions(CRefactory.OPTION_ASK_SCOPE | + CRefactory.OPTION_IN_COMMENT | + CRefactory.OPTION_IN_MACRO_DEFINITION); + setOptionsForcingPreview(-1); + setOptionsEnablingScope(-1); + } + + + @Override + protected int getAcceptedLocations(int selectedOptions) { + return selectedOptions | CRefactory.OPTION_IN_INCLUDE_DIRECTIVE; + } +} diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/rename/CRenameLocalProcessor.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/rename/CRenameLocalProcessor.java new file mode 100644 index 00000000000..9a74e883722 --- /dev/null +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/rename/CRenameLocalProcessor.java @@ -0,0 +1,87 @@ +/******************************************************************************* + * Copyright (c) 2004, 2008 Wind River Systems, Inc. and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Markus Schorn - initial API and implementation + ******************************************************************************/ +package org.eclipse.cdt.internal.ui.refactoring.rename; + +import java.util.ArrayList; +import java.util.Iterator; + +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.ltk.core.refactoring.RefactoringStatus; + +import org.eclipse.cdt.core.dom.ast.DOMException; +import org.eclipse.cdt.core.dom.ast.IASTFileLocation; +import org.eclipse.cdt.core.dom.ast.IASTNode; +import org.eclipse.cdt.core.dom.ast.IParameter; +import org.eclipse.cdt.core.dom.ast.IScope; + +import org.eclipse.cdt.internal.core.dom.parser.ASTInternal; + + +/** + * Rename processor, setting up input page for a local rename. + */ +public class CRenameLocalProcessor extends CRenameProcessorDelegate { + private IScope fScope; + public CRenameLocalProcessor(CRenameProcessor input, String kind, IScope scope) { + super(input, kind); + fScope= scope; + setAvailableOptions(0); + setOptionsForcingPreview(0); + } + + // overrider + @Override + protected int getAcceptedLocations(int selectedOptions) { + return CRefactory.OPTION_IN_CODE | CRefactory.OPTION_IN_MACRO_DEFINITION | selectedOptions; + } + + // overrider + @Override + protected int getSearchScope() { + return TextSearchWrapper.SCOPE_FILE; + } + + @Override + protected void analyzeTextMatches(ArrayList matches, IProgressMonitor monitor, + RefactoringStatus status) { + if (fScope != null) { + CRefactoringArgument argument = getArgument(); + ASTManager r = getAstManager(); + int[] result= new int[] {0, Integer.MAX_VALUE}; + IScope scope= argument.getScope(); + IASTNode node= null; + try { + node = ASTInternal.getPhysicalNodeOfScope(scope); + if (argument.getBinding() instanceof IParameter) { + node= node.getParent(); + } + } catch (DOMException e) { + r.handleDOMException(argument.getTranslationUnit(), e, status); + } + if (node != null) { + IASTFileLocation loc= ASTManager.getLocationInTranslationUnit(node); + if (loc != null) { + result[0]= loc.getNodeOffset(); + result[1]= result[0] + loc.getNodeLength(); + } + } + int[] range= result; + for (Iterator iter = matches.iterator(); iter.hasNext();) { + CRefactoringMatch m = (CRefactoringMatch) iter.next(); + int off= m.getOffset(); + if (off < range[0] || off > range[1]) { + iter.remove(); + } + } + } + super.analyzeTextMatches(matches, monitor, status); + } +} diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/rename/CRenameMacroProcessor.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/rename/CRenameMacroProcessor.java new file mode 100644 index 00000000000..fb6be0784d0 --- /dev/null +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/rename/CRenameMacroProcessor.java @@ -0,0 +1,49 @@ +/******************************************************************************* + * Copyright (c) 2005, 2008 Wind River Systems, Inc and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Markus Schorn - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.ui.refactoring.rename; + +import java.util.ArrayList; +import java.util.Iterator; + +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.ltk.core.refactoring.RefactoringStatus; + + +/** + * Rename processor that sets up the input page for renaming a global entity. + */ +public class CRenameMacroProcessor extends CRenameGlobalProcessor { + + public CRenameMacroProcessor(CRenameProcessor processor, String name) { + super(processor, name); + setAvailableOptions(CRefactory.OPTION_ASK_SCOPE | + CRefactory.OPTION_IN_CODE | + CRefactory.OPTION_IN_COMMENT | + CRefactory.OPTION_IN_PREPROCESSOR_DIRECTIVE); + } + + @Override + protected int getAcceptedLocations(int selectedOptions) { + return selectedOptions | CRefactory.OPTION_IN_MACRO_DEFINITION; + } + + @Override + protected void analyzeTextMatches(ArrayList matches, IProgressMonitor monitor, + RefactoringStatus status) { + for (Iterator iter = matches.iterator(); iter.hasNext();) { + CRefactoringMatch m = (CRefactoringMatch) iter.next(); + if ((m.getLocation() & CRefactory.OPTION_IN_PREPROCESSOR_DIRECTIVE) != 0) { + m.setASTInformation(CRefactoringMatch.AST_REFERENCE); + } + } + super.analyzeTextMatches(matches, monitor, status); + } +} diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/rename/CRenameMethodProcessor.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/rename/CRenameMethodProcessor.java new file mode 100644 index 00000000000..332a0a8a45f --- /dev/null +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/rename/CRenameMethodProcessor.java @@ -0,0 +1,93 @@ +/******************************************************************************* + * Copyright (c) 2005, 2008 Wind River Systems, Inc. and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Markus Schorn - initial API and implementation + ******************************************************************************/ +package org.eclipse.cdt.internal.ui.refactoring.rename; + +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.OperationCanceledException; +import org.eclipse.ltk.core.refactoring.RefactoringStatus; +import org.eclipse.ltk.core.refactoring.participants.CheckConditionsContext; + +import org.eclipse.cdt.core.dom.ast.DOMException; +import org.eclipse.cdt.core.dom.ast.IASTCompositeTypeSpecifier; +import org.eclipse.cdt.core.dom.ast.IASTName; +import org.eclipse.cdt.core.dom.ast.IASTNode; +import org.eclipse.cdt.core.dom.ast.IBinding; +import org.eclipse.cdt.core.dom.ast.IScope; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPConstructor; + +import org.eclipse.cdt.internal.core.dom.parser.ASTInternal; + + +/** + * Rename processor for methods. + */ +public class CRenameMethodProcessor extends CRenameGlobalProcessor { + + public CRenameMethodProcessor(CRenameProcessor processor, String kind) { + super(processor, kind); + } + + @Override + public RefactoringStatus checkInitialConditions(IProgressMonitor pm) + throws OperationCanceledException, CoreException { + CRefactoringArgument argument= getArgument(); + IBinding binding= argument.getBinding(); + if (binding instanceof ICPPConstructor) { + return RefactoringStatus.createFatalErrorStatus(Messages.getString("CRenameMethodProcessor.fatalError.renameConstructor")); //$NON-NLS-1$ + } + String identifier= argument.getName(); + if (identifier.startsWith("~")) { //$NON-NLS-1$ + return RefactoringStatus.createFatalErrorStatus(Messages.getString("CRenameMethodProcessor.fatalError.renameDestructor")); //$NON-NLS-1$ + } + if (identifier.startsWith("operator") && //$NON-NLS-1$ + identifier.length() > 8 && + !CRefactoringUtils.isIdentifierChar(identifier.charAt(8))) { + return RefactoringStatus.createFatalErrorStatus(Messages.getString("CRenameMethodProcessor.fatalError.renameOperator")); //$NON-NLS-1$ + } + return super.checkInitialConditions(pm); + } + + @Override + public RefactoringStatus checkFinalConditions(IProgressMonitor monitor, + CheckConditionsContext context) throws OperationCanceledException, CoreException { + CRefactoringArgument argument= getArgument(); + RefactoringStatus result= new RefactoringStatus(); + IScope scope= argument.getScope(); + if (scope != null) { + IASTNode node= null; + try { + node = ASTInternal.getPhysicalNodeOfScope(scope); + } catch (DOMException e) { + getAstManager().handleDOMException(argument.getTranslationUnit(), e, result); + } + if (node instanceof IASTCompositeTypeSpecifier) { + IASTCompositeTypeSpecifier se= (IASTCompositeTypeSpecifier) node; + IASTName name= ASTManager.getSimpleName(se.getName()); + if (getReplacementText().equals(name.toString())) { + return RefactoringStatus.createFatalErrorStatus(Messages.getString("CRenameMethodProcessor.fatalError.renameToConstructor")); //$NON-NLS-1$ + } + if (getReplacementText().startsWith("~")) { //$NON-NLS-1$ + return RefactoringStatus.createFatalErrorStatus(Messages.getString("CRenameMethodProcessor.fatalError.renameToDestructor")); //$NON-NLS-1$); + } + if (!CRefactoringUtils.checkIdentifier(getReplacementText())) { + result.merge(RefactoringStatus.createErrorStatus(Messages.getString("CRenameMethodProcessor.warning.illegalCharacters"))); //$NON-NLS-1$ + } + } + } + if (argument.getArgumentKind() == CRefactory.ARGUMENT_VIRTUAL_METHOD) { + result.merge(RefactoringStatus.createWarningStatus(Messages.getString("CRenameMethodProcessor.warning.renameVirtual"))); //$NON-NLS-1$ + } + + result.merge(super.checkFinalConditions(monitor, context)); + return result; + } +} diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/rename/CRenameProcessor.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/rename/CRenameProcessor.java new file mode 100644 index 00000000000..45c41ea33d1 --- /dev/null +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/rename/CRenameProcessor.java @@ -0,0 +1,290 @@ +/******************************************************************************* + * Copyright (c) 2004, 2008 Wind River Systems, Inc. and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Markus Schorn - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.ui.refactoring.rename; + +import java.text.MessageFormat; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import org.eclipse.core.resources.IFile; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.NullProgressMonitor; +import org.eclipse.core.runtime.OperationCanceledException; +import org.eclipse.ltk.core.refactoring.Change; +import org.eclipse.ltk.core.refactoring.RefactoringStatus; +import org.eclipse.ltk.core.refactoring.participants.CheckConditionsContext; +import org.eclipse.ltk.core.refactoring.participants.ParticipantManager; +import org.eclipse.ltk.core.refactoring.participants.RefactoringParticipant; +import org.eclipse.ltk.core.refactoring.participants.RenameArguments; +import org.eclipse.ltk.core.refactoring.participants.RenameParticipant; +import org.eclipse.ltk.core.refactoring.participants.RenameProcessor; +import org.eclipse.ltk.core.refactoring.participants.SharableParticipants; + +import org.eclipse.cdt.core.CCProjectNature; +import org.eclipse.cdt.core.CCorePlugin; +import org.eclipse.cdt.core.dom.ast.IBinding; +import org.eclipse.cdt.core.index.IIndex; +import org.eclipse.cdt.core.model.CoreModel; +import org.eclipse.cdt.core.model.ICProject; + + +/** + * This is the processor used for the rename. It decides which of the delegates to + * use and forwards further calls to the delegate. + */ +public class CRenameProcessor extends RenameProcessor { + public static final String IDENTIFIER= "org.eclips.cdt.refactoring.RenameProcessor"; //$NON-NLS-1$ + + private CRefactoringArgument fArgument; + private CRenameProcessorDelegate fDelegate; + private String fReplacementText; + private String fWorkingSet; + private int fScope; + private int fSelectedOptions; + private CRefactory fManager; + private ASTManager fAstManager; + private IIndex fIndex; + + public CRenameProcessor(CRefactory refactoringManager, CRefactoringArgument arg) { + fManager= refactoringManager; + fArgument= arg; + fAstManager= new ASTManager(arg); + } + + public CRefactoringArgument getArgument() { + return fArgument; + } + + // overrider + @Override + public Object[] getElements() { + return new Object[] {fArgument.getBinding()}; + } + + // overrider + @Override + public String getProcessorName() { + String result= null; + if (fDelegate != null) { + result= fDelegate.getProcessorName(); + } + if (result == null) { + String identifier= getArgument().getName(); + if (identifier != null && identifier.length() > 0) { + result= MessageFormat.format(Messages.getString("CRenameTopProcessor.wizard.title"), //$NON-NLS-1$ + new Object[] {identifier}); + } + } + if (result == null) { + result= Messages.getString("CRenameTopProcessor.wizard.backup.title"); //$NON-NLS-1$ + } + + return result; + } + + // overrider + @Override + public boolean isApplicable() throws CoreException { + return true; + } + + // overrider + @Override + public RefactoringStatus checkInitialConditions(IProgressMonitor pm) + throws CoreException, OperationCanceledException { + String identifier= null; + RefactoringStatus status= new RefactoringStatus(); + if (fArgument != null) { + fAstManager.analyzeArgument(fIndex, pm, status); + identifier= fArgument.getName(); + } + if (identifier == null || identifier.length() < 1) { + status.addFatalError(Messages.getString("CRenameTopProcessor.error.invalidTextSelection")); //$NON-NLS-1$ + return status; + } + IFile file= fArgument.getSourceFile(); + IPath path= null; + if (file != null) { + path= file.getLocation(); + } + if (path == null) { + return RefactoringStatus.createFatalErrorStatus(Messages.getString("CRenameTopProcessor.error.renameWithoutSourceFile")); //$NON-NLS-1$ + } + + fDelegate= createDelegate(); + if (fDelegate == null) { + status.addFatalError(Messages.getString("CRenameTopProcessor.error.invalidName")); //$NON-NLS-1$ + return status; + } + RefactoringStatus s1= fDelegate.checkInitialConditions(new NullProgressMonitor()); + status.merge(s1); + return status; + } + + private CRenameProcessorDelegate createDelegate() { + switch (fArgument.getArgumentKind()) { + case CRefactory.ARGUMENT_LOCAL_VAR: + return new CRenameLocalProcessor(this, + Messages.getString("CRenameTopProcessor.localVar"), //$NON-NLS-1$ + fArgument.getScope()); + case CRefactory.ARGUMENT_PARAMETER: + return new CRenameLocalProcessor(this, + Messages.getString("CRenameTopProcessor.parameter"), //$NON-NLS-1$ + fArgument.getScope()); + case CRefactory.ARGUMENT_FILE_LOCAL_VAR: + return new CRenameLocalProcessor(this, + Messages.getString("CRenameTopProcessor.filelocalVar"), //$NON-NLS-1$ + null); + case CRefactory.ARGUMENT_GLOBAL_VAR: + return new CRenameGlobalProcessor(this, Messages.getString("CRenameTopProcessor.globalVar")); //$NON-NLS-1$ + case CRefactory.ARGUMENT_ENUMERATOR: + return new CRenameGlobalProcessor(this, Messages.getString("CRenameTopProcessor.enumerator")); //$NON-NLS-1$ + case CRefactory.ARGUMENT_FIELD: + return new CRenameGlobalProcessor(this, Messages.getString("CRenameTopProcessor.field")); //$NON-NLS-1$ + case CRefactory.ARGUMENT_FILE_LOCAL_FUNCTION: + return new CRenameLocalProcessor(this, + Messages.getString("CRenameTopProcessor.filelocalFunction"), //$NON-NLS-1$ + null); + case CRefactory.ARGUMENT_GLOBAL_FUNCTION: + return new CRenameGlobalProcessor(this, Messages.getString("CRenameTopProcessor.globalFunction")); //$NON-NLS-1$ + case CRefactory.ARGUMENT_VIRTUAL_METHOD: + return new CRenameMethodProcessor(this, Messages.getString("CRenameTopProcessor.virtualMethod")); //$NON-NLS-1$ + case CRefactory.ARGUMENT_NON_VIRTUAL_METHOD: + return new CRenameMethodProcessor(this, Messages.getString("CRenameTopProcessor.method")); //$NON-NLS-1$ + case CRefactory.ARGUMENT_CLASS_TYPE: + return new CRenameClassProcessor(this, Messages.getString("CRenameTopProcessor.type")); //$NON-NLS-1$ + case CRefactory.ARGUMENT_NAMESPACE: + return new CRenameTypeProcessor(this, Messages.getString("CRenameTopProcessor.namespace")); //$NON-NLS-1$ + case CRefactory.ARGUMENT_TYPE: + return new CRenameTypeProcessor(this, Messages.getString("CRenameTopProcessor.type")); //$NON-NLS-1$ + case CRefactory.ARGUMENT_MACRO: + return new CRenameMacroProcessor(this, Messages.getString("CRenameTopProcessor.macro")); //$NON-NLS-1$ + case CRefactory.ARGUMENT_INCLUDE_DIRECTIVE: + return new CRenameIncludeProcessor(this, Messages.getString("CRenameIncludeProcessor.includeDirective")); //$NON-NLS-1$ + default: + return null; + } + } + + // overrider + @Override + public RefactoringStatus checkFinalConditions(IProgressMonitor pm, + CheckConditionsContext context) throws CoreException, + OperationCanceledException { + return fDelegate.checkFinalConditions(pm, context); + } + + // overrider + @Override + public Change createChange(IProgressMonitor pm) throws CoreException, + OperationCanceledException { + return fDelegate.createChange(pm); + } + + // overrider + @Override + public RefactoringParticipant[] loadParticipants(RefactoringStatus status, + SharableParticipants sharedParticipants) throws CoreException { + RenameArguments arguments= new RenameArguments(getReplacementText(), + true); + final String[] natures= {CCProjectNature.CC_NATURE_ID, CCProjectNature.C_NATURE_ID}; + List result= new ArrayList(); + IBinding binding= getArgument().getBinding(); + if (binding != null) { + result.addAll(Arrays.asList(ParticipantManager.loadRenameParticipants(status, + this, binding, arguments, natures, sharedParticipants))); + } + return result.toArray(new RefactoringParticipant[result.size()]); + } + + // options for the input page in the refactoring wizard + public int getAvailableOptions() { + if (fDelegate == null) { + return 0; + } + return fDelegate.getAvailableOptions(); + } + + // options for the input page that trigger the preview + public int getOptionsForcingPreview() { + if (fDelegate == null) { + return 0; + } + return fDelegate.getOptionsForcingPreview(); + } + + // options for the input page that trigger the preview + public int getOptionsEnablingScope() { + if (fDelegate == null) { + return 0; + } + return fDelegate.getOptionsEnablingScope(); + } + + // overrider + @Override + public String getIdentifier() { + return IDENTIFIER; + } + + public int getScope() { + return fScope; + } + public void setScope(int scope) { + fScope = scope; + } + public int getSelectedOptions() { + return fSelectedOptions; + } + public void setSelectedOptions(int selectedOptions) { + fSelectedOptions = selectedOptions; + } + public String getWorkingSet() { + return fWorkingSet; + } + public void setWorkingSet(String workingSet) { + fWorkingSet = workingSet; + } + public String getReplacementText() { + return fReplacementText; + } + public void setReplacementText(String replacementText) { + fReplacementText = replacementText; + } + public CRefactory getManager() { + return fManager; + } + public ASTManager getAstManager() { + return fAstManager; + } + + public void lockIndex() throws CoreException, InterruptedException { + if (fIndex == null) { + ICProject[] projects= CoreModel.getDefault().getCModel().getCProjects(); + fIndex= CCorePlugin.getIndexManager().getIndex(projects); + } + fIndex.acquireReadLock(); + } + + public void unlockIndex() { + if (fIndex != null) { + fIndex.releaseReadLock(); + } + fIndex= null; + } + + public IIndex getIndex() { + return fIndex; + } +} diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/rename/CRenameProcessorDelegate.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/rename/CRenameProcessorDelegate.java new file mode 100644 index 00000000000..cd77fb13daf --- /dev/null +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/rename/CRenameProcessorDelegate.java @@ -0,0 +1,316 @@ +/******************************************************************************* + * Copyright (c) 2004, 2008 Wind River Systems, Inc. and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Markus Schorn - initial API and implementation + * IBM Corporation - Bug 112366 + ******************************************************************************/ +package org.eclipse.cdt.internal.ui.refactoring.rename; + +import java.text.MessageFormat; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.HashSet; +import java.util.Iterator; + +import org.eclipse.core.resources.IFile; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.OperationCanceledException; +import org.eclipse.core.runtime.SubProgressMonitor; +import org.eclipse.ltk.core.refactoring.Change; +import org.eclipse.ltk.core.refactoring.CompositeChange; +import org.eclipse.ltk.core.refactoring.RefactoringStatus; +import org.eclipse.ltk.core.refactoring.TextEditChangeGroup; +import org.eclipse.ltk.core.refactoring.TextFileChange; +import org.eclipse.ltk.core.refactoring.participants.CheckConditionsContext; +import org.eclipse.ltk.core.refactoring.participants.ValidateEditChecker; +import org.eclipse.text.edits.MultiTextEdit; +import org.eclipse.text.edits.ReplaceEdit; +import org.eclipse.text.edits.TextEditGroup; + +import org.eclipse.cdt.core.dom.ast.IBinding; +import org.eclipse.cdt.ui.refactoring.CTextFileChange; + + +/** + * Abstract base for all different rename processors used by the top + * processor. + */ +public abstract class CRenameProcessorDelegate { + private CRenameProcessor fTopProcessor; + private ArrayList fMatches= null; + protected String fProcessorBaseName; + private int fAvailableOptions= + CRefactory.OPTION_ASK_SCOPE | + CRefactory.OPTION_IN_CODE | + CRefactory.OPTION_IN_COMMENT | + CRefactory.OPTION_IN_MACRO_DEFINITION | + CRefactory.OPTION_IN_STRING_LITERAL; + + private int fOptionsForcingPreview= + CRefactory.OPTION_IN_CODE | + CRefactory.OPTION_IN_COMMENT | + CRefactory.OPTION_IN_MACRO_DEFINITION | + CRefactory.OPTION_IN_PREPROCESSOR_DIRECTIVE | + CRefactory.OPTION_IN_STRING_LITERAL; + + private int fOptionsEnablingScope= fOptionsForcingPreview; + + + protected CRenameProcessorDelegate(CRenameProcessor topProcessor, String name) { + fTopProcessor= topProcessor; + fProcessorBaseName= name; + } + + final public CRefactoringArgument getArgument() { + return fTopProcessor.getArgument(); + } + final public String getReplacementText() { + return fTopProcessor.getReplacementText(); + } + final public int getSelectedScope() { + return fTopProcessor.getScope(); + } + final public int getSelectedOptions() { + return fTopProcessor.getSelectedOptions(); + } + final public String getSelectedWorkingSet() { + return fTopProcessor.getWorkingSet(); + } + final public CRefactory getManager() { + return fTopProcessor.getManager(); + } + final public ASTManager getAstManager() { + return fTopProcessor.getAstManager(); + } + final public String getProcessorName() { + String identifier= getArgument().getName(); + if (identifier != null) { + return MessageFormat.format( + Messages.getString("CRenameProcessorDelegate.wizard.title"), //$NON-NLS-1$ + new Object[] {fProcessorBaseName, identifier}); + } + return null; + } + + /** + * The options presented by the page in the refactoring wizard. + */ + public void setAvailableOptions(int options) { + fAvailableOptions= options; + } + final int getAvailableOptions() { + return fAvailableOptions; + } + + /** + * The options each of which forces the preview, when selected. + */ + public void setOptionsForcingPreview(int options) { + fOptionsForcingPreview= options; + } + + final int getOptionsForcingPreview() { + return fOptionsForcingPreview; + } + + /** + * The options that need the scope definition. When one of them is + * selected, the scope options are enabled. + */ + public void setOptionsEnablingScope(int options) { + fOptionsEnablingScope= options; + } + + final int getOptionsEnablingScope() { + return fOptionsEnablingScope; + } + + protected int getSearchScope() { + return getSelectedScope(); + } + + public RefactoringStatus checkInitialConditions(IProgressMonitor pm) throws CoreException, OperationCanceledException { + return new RefactoringStatus(); + } + + public RefactoringStatus checkFinalConditions(IProgressMonitor monitor, CheckConditionsContext context) throws CoreException, OperationCanceledException { + RefactoringStatus result= new RefactoringStatus(); + monitor.beginTask(Messages.getString("CRenameProcessorDelegate.task.checkFinalCondition"), 2); //$NON-NLS-1$ + IFile file= getArgument().getSourceFile(); + //assert file!=null; + + // perform text-search + fMatches= new ArrayList(); + TextSearchWrapper txtSearch= getManager().getTextSearch(); + IStatus stat= txtSearch.searchWord(getSearchScope(), file, getSelectedWorkingSet(), + getManager().getCCppPatterns(), getArgument().getName(), + new SubProgressMonitor(monitor, 1), fMatches); + if (monitor.isCanceled()) { + throw new OperationCanceledException(); + } + result.merge(RefactoringStatus.create(stat)); + if (result.hasFatalError()) { + return result; + } + selectMatchesByLocation(fMatches); + analyzeTextMatches(fMatches, new SubProgressMonitor(monitor, 1), result); + if (result.hasFatalError()) { + return result; + } + + HashSet fileset= new HashSet(); + int potentialMatchCount= 0; + int commentCount=0; + for (Iterator iter = fMatches.iterator(); iter.hasNext();) { + CRefactoringMatch tm = iter.next(); + if (tm.isInComment()) { + commentCount++; + fileset.add(tm.getFile()); + } + else { + switch(tm.getAstInformation()) { + case CRefactoringMatch.AST_REFERENCE_OTHER: + iter.remove(); + break; + case CRefactoringMatch.POTENTIAL: + potentialMatchCount++; + fileset.add(tm.getFile()); + break; + default: + fileset.add(tm.getFile()); + break; + } + } + } + if (potentialMatchCount != 0) { + String msg= null; + if (potentialMatchCount == 1) { + msg= Messages.getString("CRenameProcessorDelegate.warning.potentialMatch.singular"); //$NON-NLS-1$ + } + else { + msg= MessageFormat.format( + Messages.getString("CRenameProcessorDelegate.warning.potentialMatch.plural"), //$NON-NLS-1$ + new Object[]{new Integer(potentialMatchCount)}); + } + result.addWarning(msg); + } + if (commentCount != 0) { + String msg= null; + if (commentCount == 1) { + msg= Messages.getString("CRenameProcessorDelegate.warning.commentMatch.singular"); //$NON-NLS-1$ + } + else { + msg= MessageFormat.format( + Messages.getString("CRenameProcessorDelegate.warning.commentMatch.plural"), //$NON-NLS-1$ + new Object[]{new Integer(commentCount)}); + } + result.addWarning(msg); + } + IFile[] files= fileset.toArray(new IFile[fileset.size()]); + if (context != null) { + ValidateEditChecker editChecker= + (ValidateEditChecker) context.getChecker(ValidateEditChecker.class); + editChecker.addFiles(files); + } + monitor.done(); + return result; + } + + protected void analyzeTextMatches(ArrayList matches, IProgressMonitor monitor, RefactoringStatus status) { + CRefactoringArgument argument= getArgument(); + IBinding[] renameBindings= getBindingsToBeRenamed(status); + if (renameBindings != null && renameBindings.length > 0 && + argument.getArgumentKind() != CRefactory.ARGUMENT_UNKNOWN) { + ASTManager mngr= getAstManager(); + mngr.setValidBindings(renameBindings); + mngr.setRenameTo(getReplacementText()); + mngr.analyzeTextMatches(fTopProcessor.getIndex(), matches, monitor, status); + } + } + + private void selectMatchesByLocation(ArrayList matches) { + int acceptTextLocation= getAcceptedLocations(getSelectedOptions()); + for (Iterator iter = matches.iterator(); iter.hasNext();) { + CRefactoringMatch match = iter.next(); + int location= match.getLocation(); + if (location != 0 && ((location & acceptTextLocation) == 0)) { + iter.remove(); + } + } + } + + protected int getAcceptedLocations(int selectedOptions) { + return selectedOptions; + } + + public Change createChange(IProgressMonitor pm) throws CoreException, OperationCanceledException { + if (fMatches.size() == 0) { + return null; + } + Collections.sort(fMatches, new Comparator(){ + public int compare(CRefactoringMatch m1, CRefactoringMatch m2) { + IFile f1= m1.getFile(); + IFile f2= m2.getFile(); + int cmp= f1.getName().compareTo(f2.getName()); + if (cmp != 0) return cmp; + + cmp= f1.getFullPath().toString().compareTo(f2.getFullPath().toString()); + if (cmp != 0) return cmp; + + return m1.getOffset() - m2.getOffset(); + }}); + pm.beginTask(Messages.getString("CRenameProcessorDelegate.task.createChange"), fMatches.size()); //$NON-NLS-1$ + final String identifier= getArgument().getName(); + final String replacement= getReplacementText(); + CompositeChange overallChange= new CompositeChange(getProcessorName()); + IFile file= null; + TextFileChange fileChange= null; + MultiTextEdit fileEdit= null; + for (Iterator iter = fMatches.iterator(); iter.hasNext();) { + CRefactoringMatch match= iter.next(); + switch(match.getAstInformation()) { + case CRefactoringMatch.AST_REFERENCE_OTHER: + continue; + case CRefactoringMatch.IN_COMMENT: + case CRefactoringMatch.POTENTIAL: + break; + case CRefactoringMatch.AST_REFERENCE: + break; + } + if (match.getAstInformation() != CRefactoringMatch.AST_REFERENCE_OTHER) { + IFile mfile= match.getFile(); + if (file==null || !file.equals(mfile)) { + file= mfile; + fileEdit= new MultiTextEdit(); + fileChange = new CTextFileChange(file.getName(), file); + fileChange.setEdit(fileEdit); + overallChange.add(fileChange); + } + + ReplaceEdit replaceEdit= new ReplaceEdit(match.getOffset(), + identifier.length(), replacement); + fileEdit.addChild(replaceEdit); + TextEditGroup editGroup= new TextEditGroup(match.getLabel(), replaceEdit); + TextEditChangeGroup changeGroup= new TextEditChangeGroup(fileChange, editGroup); + fileChange.addTextEditChangeGroup(changeGroup); + } + pm.worked(1); + } + return overallChange; + } + + /** + * Returns the array of bindings that must be renamed + */ + protected IBinding[] getBindingsToBeRenamed(RefactoringStatus status) { + return new IBinding[] {getArgument().getBinding()}; + } +} diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/rename/CRenameRefactoring.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/rename/CRenameRefactoring.java new file mode 100644 index 00000000000..61cfd2401bc --- /dev/null +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/rename/CRenameRefactoring.java @@ -0,0 +1,32 @@ +/******************************************************************************* + * Copyright (c) 2004, 2008 Wind River Systems, Inc. and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Markus Schorn - initial API and implementation + ******************************************************************************/ +package org.eclipse.cdt.internal.ui.refactoring.rename; + +import org.eclipse.ltk.core.refactoring.participants.ProcessorBasedRefactoring; +import org.eclipse.ltk.core.refactoring.participants.RefactoringProcessor; + +/** + * Refactoring implementation using a refactoring processor. + */ +public class CRenameRefactoring extends ProcessorBasedRefactoring { + + private CRenameProcessor fProcessor; + + public CRenameRefactoring(CRenameProcessor processor) { + super(processor); + fProcessor= processor; + } + + @Override + public RefactoringProcessor getProcessor() { + return fProcessor; + } +} diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/rename/CRenameRefactoringInputPage.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/rename/CRenameRefactoringInputPage.java new file mode 100644 index 00000000000..8734d11b436 --- /dev/null +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/rename/CRenameRefactoringInputPage.java @@ -0,0 +1,559 @@ +/******************************************************************************* + * Copyright (c) 2004, 2008 Wind River Systems, Inc. and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Markus Schorn - initial API and implementation + ******************************************************************************/ +package org.eclipse.cdt.internal.ui.refactoring.rename; + +import org.eclipse.jface.dialogs.Dialog; +import org.eclipse.jface.dialogs.IDialogSettings; +import org.eclipse.jface.window.Window; +import org.eclipse.ltk.ui.refactoring.UserInputWizardPage; +import org.eclipse.osgi.util.NLS; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.KeyEvent; +import org.eclipse.swt.events.KeyListener; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.events.SelectionListener; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Text; +import org.eclipse.ui.IWorkingSet; +import org.eclipse.ui.IWorkingSetManager; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.dialogs.IWorkingSetSelectionDialog; + +import org.eclipse.cdt.ui.CUIPlugin; + + +/** + * Input page added to the standard refactoring wizard. + */ +public class CRenameRefactoringInputPage extends UserInputWizardPage { + + public static final String PAGE_NAME = "RenameRefactoringPage"; //$NON-NLS-1$ + + private static final String KEY_REFERENCES_INV = "references_inv"; //$NON-NLS-1$ + private static final String KEY_COMMENT = "comment"; //$NON-NLS-1$ + private static final String KEY_STRING = "string"; //$NON-NLS-1$ + private static final String KEY_INACTIVE = "inactive"; //$NON-NLS-1$ + private static final String KEY_SCOPE = "scope"; //$NON-NLS-1$ + private static final String KEY_WORKING_SET_NAME = "workingset"; //$NON-NLS-1$ + + private static final String KEY_INCLUDE = "include"; //$NON-NLS-1$ + private static final String KEY_MACRO_DEFINITION = "macroDefinition"; //$NON-NLS-1$ + private static final String KEY_PREPROCESSOR = "preprocessor"; //$NON-NLS-1$ + + private IDialogSettings fDialogSettings; + private String fSearchString; + private int fOptions; + private int fForcePreviewOptions= 0; + private int fEnableScopeOptions; + + private Text fNewName; + private Button fWorkspace; + private Button fDependent; + private Button fInComment; + private Button fInString; + private Button fInInclude; + private Button fInInactiveCode; + private Button fReferences; + private Button fSingle; + private Button fWorkingSet; + private Text fWorkingSetSpec; + private Button fWorkingSetButton; + private Button fInMacro; + private Button fInPreprocessor; + + public CRenameRefactoringInputPage() { + super(PAGE_NAME); + String key= "CRenameRefactoringInputPage"; //$NON-NLS-1$ + IDialogSettings ds= CUIPlugin.getDefault().getDialogSettings(); + fDialogSettings= ds.getSection(key); + if (fDialogSettings == null) { + fDialogSettings= ds.addNewSection(key); + } + } + + private boolean hasOption(int options) { + return (fOptions & options) == options; + } + + // overrider + public void createControl(Composite parent) { + CRenameProcessor processor= getRenameProcessor(); + fSearchString= processor.getArgument().getName(); + fOptions= processor.getAvailableOptions(); + fForcePreviewOptions= processor.getOptionsForcingPreview(); + fEnableScopeOptions= processor.getOptionsEnablingScope(); + + Composite top= new Composite(parent, SWT.NONE); + initializeDialogUnits(top); + setControl(top); + + top.setLayout(new GridLayout(2, false)); + + // new name + Composite group= top; + GridData gd; + + Label l= new Label(group, SWT.NONE); + l.setText(Messages.getString("CRenameRefactoringInputPage.newIdentifier.label")); //$NON-NLS-1$ + fNewName= new Text(group, SWT.BORDER); + fNewName.setText(fSearchString); + fNewName.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + fNewName.selectAll(); + + boolean skippedLine= false; + // specify the scope + if (hasOption(CRefactory.OPTION_ASK_SCOPE)) { + skipLine(top); + new Label(top, SWT.NONE).setText(Messages.getString("CRenameRefactoringInputPage.label.scope")); //$NON-NLS-1$ + skippedLine= true; + + group= new Composite(top, SWT.NONE); + group.setLayoutData(gd= new GridData(GridData.FILL_HORIZONTAL)); + gd.horizontalSpan= 2; + group.setLayout(new GridLayout(3, false)); + + fWorkspace= new Button(group, SWT.RADIO); + fWorkspace.setText(Messages.getString("CRenameRefactoringInputPage.button.scope.workspace")); //$NON-NLS-1$ + fWorkspace.setLayoutData(gd= new GridData()); + gd.horizontalSpan= 3; + + fDependent= new Button(group, SWT.RADIO); + fDependent.setText(Messages.getString("CRenameRefactoringInputPage.button.scope.releatedprojects")); //$NON-NLS-1$ + fDependent.setLayoutData(gd= new GridData()); + gd.horizontalSpan= 3; + + fSingle= new Button(group, SWT.RADIO); + fSingle.setText(Messages.getString("CRenameRefactoringInputPage.button.singleProject")); //$NON-NLS-1$ + fSingle.setLayoutData(gd= new GridData()); + gd.horizontalSpan= 3; + + fWorkingSet= new Button(group, SWT.RADIO); + fWorkingSet.setText(Messages.getString("CRenameRefactoringInputPage.button.workingSet")); //$NON-NLS-1$ + + fWorkingSetSpec= new Text(group, SWT.BORDER|SWT.READ_ONLY); + fWorkingSetSpec.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + fWorkingSetButton= new Button(group, SWT.PUSH); + fWorkingSetButton.setText(Messages.getString("CRenameRefactoringInputPage.button.chooseWorkingSet")); //$NON-NLS-1$ + setButtonLayoutData(fWorkingSetButton); + } + + group= null; + if (hasOption(CRefactory.OPTION_IN_CODE)) { + group= createLabelAndGroup(group, skippedLine, top); + fReferences= new Button(group, SWT.CHECK); + fReferences.setText(Messages.getString("CRenameRefactoringInputPage.update.label")); //$NON-NLS-1$ + } + if (hasOption(CRefactory.OPTION_IN_INACTIVE_CODE)) { + group= createLabelAndGroup(group, skippedLine, top); + fInInactiveCode= new Button(group, SWT.CHECK); + fInInactiveCode.setText(Messages.getString("CRenameRefactoringInputPage.button.inactiveCode")); //$NON-NLS-1$ + } + if (hasOption(CRefactory.OPTION_IN_COMMENT)) { + group= createLabelAndGroup(group, skippedLine, top); + fInComment= new Button(group, SWT.CHECK); + fInComment.setText(Messages.getString("CRenameRefactoringInputPage.button.comments")); //$NON-NLS-1$ + } + if (hasOption(CRefactory.OPTION_IN_STRING_LITERAL)) { + group= createLabelAndGroup(group, skippedLine, top); + fInString= new Button(group, SWT.CHECK); + fInString.setText(Messages.getString("CRenameRefactoringInputPage.button.strings")); //$NON-NLS-1$ + } + + if (hasOption(CRefactory.OPTION_IN_MACRO_DEFINITION)) { + group= createLabelAndGroup(group, skippedLine, top); + fInMacro= new Button(group, SWT.CHECK); + fInMacro.setText(Messages.getString("CRenameRefactoringInputPage.button.macrodefinitions")); //$NON-NLS-1$ + } + if (hasOption(CRefactory.OPTION_IN_INCLUDE_DIRECTIVE)) { + group= createLabelAndGroup(group, skippedLine, top); + fInInclude= new Button(group, SWT.CHECK); + fInInclude.setText(Messages.getString("CRenameRefactoringInputPage.button.includes")); //$NON-NLS-1$ + } + if (hasOption(CRefactory.OPTION_IN_PREPROCESSOR_DIRECTIVE)) { + group= createLabelAndGroup(group, skippedLine, top); + fInPreprocessor= new Button(group, SWT.CHECK); + fInPreprocessor.setText(Messages.getString("CRenameRefactoringInputPage.button.preprocessor")); //$NON-NLS-1$ + } + Dialog.applyDialogFont(top); + hookSelectionListeners(); + readPreferences(); + onSelectOption(); // transfers the option to the refactoring/ enablement + updatePageComplete(); + } + + private Composite createLabelAndGroup(Composite group, boolean skippedLine, + Composite top) { + if (group != null) { + return group; + } + if (!skippedLine) { + skipLine(top); + } + GridData gd; + new Label(top, SWT.NONE).setText(Messages.getString("CRenameRefactoringInputPage.label.updateWithin")); //$NON-NLS-1$ + group= new Composite(top, SWT.NONE); + group.setLayoutData(gd= new GridData()); + gd.horizontalSpan= 2; + group.setLayout(new GridLayout(1, true)); + return group; + } + + private void skipLine(Composite top) { + new Label(top, SWT.NONE); + new Label(top, SWT.NONE); + } + + private void hookSelectionListeners() { + fNewName.addKeyListener(new KeyListener() { + public void keyPressed(KeyEvent e) { + } + public void keyReleased(KeyEvent e) { + onKeyReleaseInNameField(); + } + }); + + registerScopeListener(fWorkspace, TextSearchWrapper.SCOPE_WORKSPACE); + registerScopeListener(fDependent, TextSearchWrapper.SCOPE_RELATED_PROJECTS); + registerScopeListener(fSingle, TextSearchWrapper.SCOPE_SINGLE_PROJECT); + registerScopeListener(fWorkingSet, TextSearchWrapper.SCOPE_WORKING_SET); + + if (fWorkingSetButton != null) { + fWorkingSetButton.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + onSelectWorkingSet(); + } + }); + } + SelectionListener listenOption= new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + onSelectOption(); + } + }; + registerOptionListener(fReferences, listenOption); + registerOptionListener(fInComment, listenOption); + registerOptionListener(fInInactiveCode, listenOption); + registerOptionListener(fInInclude, listenOption); + registerOptionListener(fInMacro, listenOption); + registerOptionListener(fInString, listenOption); + registerOptionListener(fInPreprocessor, listenOption); + } + + private void registerScopeListener(Button button, final int scope) { + if (button != null) { + button.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + onSelectedScope(scope); + } + }); + } + } + + private void registerOptionListener(Button button, SelectionListener listenOption) { + if (button != null) { + button.addSelectionListener(listenOption); + } + } + + protected void onSelectedScope(int scope) { + getRenameProcessor().setScope(scope); + updateEnablement(); + } + + private void onSelectOption() { + int selectedOptions= computeSelectedOptions(); + boolean forcePreview= fForcePreviewOptions==-1 || + (selectedOptions & fForcePreviewOptions) != 0; + getRenameProcessor().setSelectedOptions(selectedOptions); + getRefactoringWizard().setForcePreviewReview(forcePreview); + updateEnablement(); + } + + protected void onKeyReleaseInNameField() { + getRenameProcessor().setReplacementText(fNewName.getText()); + updatePageComplete(); + } + + // overrider + @Override + public void dispose() { + storePreferences(); + super.dispose(); + } + + private void readPreferences() { + CRenameProcessor processor= getRenameProcessor(); + + if (fWorkspace != null) { + int choice; + try { + choice= fDialogSettings.getInt(KEY_SCOPE); + } + catch (Exception e) { + choice= TextSearchWrapper.SCOPE_RELATED_PROJECTS; + } + + switch(choice) { + case TextSearchWrapper.SCOPE_WORKSPACE: + fWorkspace.setSelection(true); + break; + case TextSearchWrapper.SCOPE_SINGLE_PROJECT: + fSingle.setSelection(true); + break; + case TextSearchWrapper.SCOPE_WORKING_SET: + fWorkingSet.setSelection(true); + break; + default: + choice= TextSearchWrapper.SCOPE_RELATED_PROJECTS; + fDependent.setSelection(true); + break; + } + processor.setScope(choice); + + String workingSet= checkWorkingSet(fDialogSettings.get(KEY_WORKING_SET_NAME)); + fWorkingSetSpec.setText(workingSet); + processor.setWorkingSet(workingSet); + } + + if (fReferences != null) { + boolean val= !fDialogSettings.getBoolean(KEY_REFERENCES_INV); + fReferences.setSelection(val); + } + initOption(fInComment, KEY_COMMENT); + initOption(fInString, KEY_STRING); + initOption(fInInclude, KEY_INCLUDE); + initOption(fInMacro, KEY_MACRO_DEFINITION); + initOption(fInPreprocessor, KEY_PREPROCESSOR); + initOption(fInInactiveCode, KEY_INACTIVE); + } + + private int computeSelectedOptions() { + int options= 0; + options |= computeOption(fReferences, CRefactory.OPTION_IN_CODE); + options |= computeOption(fInComment, CRefactory.OPTION_IN_COMMENT); + options |= computeOption(fInString, CRefactory.OPTION_IN_STRING_LITERAL); + options |= computeOption(fInInclude, CRefactory.OPTION_IN_INCLUDE_DIRECTIVE); + options |= computeOption(fInPreprocessor, CRefactory.OPTION_IN_PREPROCESSOR_DIRECTIVE); + options |= computeOption(fInMacro, CRefactory.OPTION_IN_MACRO_DEFINITION); + options |= computeOption(fInInactiveCode, CRefactory.OPTION_IN_INACTIVE_CODE); + return options; + } + + private int computeOption(Button button, int option) { + if (button != null && button.getSelection()) { + return option; + } + return 0; + } + + private void initOption(Button button, String key) { + boolean val= false; + if (button != null) { + val= fDialogSettings.getBoolean(key); + button.setSelection(val); + } + } + + private String checkWorkingSet(String ws) { + if (ws != null && ws.length() > 0) { + IWorkingSetManager wsManager= PlatformUI.getWorkbench().getWorkingSetManager(); + if (wsManager.getWorkingSet(ws)!=null) { + return ws; + } + } + return ""; //$NON-NLS-1$ + } + + private void storePreferences() { + if (fWorkspace != null) { + int choice= TextSearchWrapper.SCOPE_RELATED_PROJECTS; + if (fWorkspace.getSelection()) { + choice= TextSearchWrapper.SCOPE_WORKSPACE; + } + else if (fSingle.getSelection()) { + choice= TextSearchWrapper.SCOPE_SINGLE_PROJECT; + } + else if (fWorkingSet.getSelection()) { + choice= TextSearchWrapper.SCOPE_WORKING_SET; + } + fDialogSettings.put(KEY_SCOPE, choice); + fDialogSettings.put(KEY_WORKING_SET_NAME, fWorkingSetSpec.getText()); + } + if (fReferences != null) { + fDialogSettings.put(KEY_REFERENCES_INV, !fReferences.getSelection()); + } + if (fInComment != null) { + fDialogSettings.put(KEY_COMMENT, fInComment.getSelection()); + } + if (fInString != null) { + fDialogSettings.put(KEY_STRING, fInString.getSelection()); + } + if (fInInclude != null) { + fDialogSettings.put(KEY_INCLUDE, fInInclude.getSelection()); + } + if (fInPreprocessor != null) { + fDialogSettings.put(KEY_PREPROCESSOR, fInPreprocessor.getSelection()); + } + if (fInMacro != null) { + fDialogSettings.put(KEY_MACRO_DEFINITION, fInMacro.getSelection()); + } + if (fInInactiveCode != null) { + fDialogSettings.put(KEY_INACTIVE, fInInactiveCode.getSelection()); + } + } + + protected void onSelectWorkingSet() { + CRenameProcessor processor= getRenameProcessor(); + String wsName= checkWorkingSet(fWorkingSetSpec.getText()); + IWorkingSetManager wsManager= PlatformUI.getWorkbench().getWorkingSetManager(); + IWorkingSetSelectionDialog dlg= + wsManager.createWorkingSetSelectionDialog(getShell(), false); + IWorkingSet currentWorkingSet= wsManager.getWorkingSet(wsName); + if (currentWorkingSet != null) { + dlg.setSelection(new IWorkingSet[] {currentWorkingSet}); + } + IWorkingSet ws= null; + if (dlg.open() == Window.OK) { + IWorkingSet wsa[]= dlg.getSelection(); + if (wsa != null && wsa.length > 0) { + ws= wsa[0]; + } + if (ws != null) { + fWorkspace.setSelection(false); + fDependent.setSelection(false); + fSingle.setSelection(false); + fWorkingSet.setSelection(true); + processor.setScope(TextSearchWrapper.SCOPE_WORKING_SET); + wsName= ws.getName(); + } + } + + fWorkingSetSpec.setText(wsName); + processor.setWorkingSet(wsName); + updateEnablement(); + } + + protected void updatePageComplete() { + String txt= fNewName.getText(); + if (txt.length() == 0 || txt.equals(fSearchString)) { + setErrorMessage(null); + setPageComplete(false); + } + else if (!isValidIdentifier(txt)) { + setErrorMessage(NLS.bind(Messages.getString("CRenameRefactoringInputPage.errorInvalidIdentifier"), txt)); //$NON-NLS-1$ + setPageComplete(false); + } + else { + setErrorMessage(null); + setPageComplete(true); + } + } + + private boolean isValidIdentifier(String txt) { + if (txt.length() < 1) { + return false; + } + char[] chars= txt.toCharArray(); + for (int i = 0; i < chars.length; i++) { + final char c = chars[i]; + switch(c) { + case '?': + // check for trigraph for backslash + if (i+2 >= chars.length) { + return false; + } + if (chars[++i] != '?') { + return false; + } + if (chars[++i] != '/') { + return false; + } + // no break, continue with check for universal character name + case '\\': + // check for universal character name + if (++i >= chars.length) { + return false; + } + int hexdigits= 0; + switch(chars[i]) { + case 'u': + hexdigits= 4; + break; + case 'U': + hexdigits= 8; + break; + default: + return false; + } + while (hexdigits > 0) { + if (++i >= chars.length) { + return false; + } + if (!isHexDigit(chars[i])) { + return false; + } + hexdigits--; + } + break; + case '_': + break; + default: + if (i==0) { + if (!Character.isLetter(c)) { + return false; + } + } + else { + if (!Character.isLetterOrDigit(c)) { + return false; + } + } + } + } + return true; + } + + private boolean isHexDigit(char c) { + return ( c >= '0' && c <= '9' ) + || ( c >= 'A' && c <= 'F' ) + || ( c >= 'a' && c <= 'f' ); + } + + protected void updateEnablement() { + boolean enable= fEnableScopeOptions==-1 || + (computeSelectedOptions() & fEnableScopeOptions) != 0; + + if (fWorkspace != null) { + fWorkspace.setEnabled(enable); + fDependent.setEnabled(enable); + fSingle.setEnabled(enable); + + boolean enableSpec= false; + fWorkingSet.setEnabled(enable); + if (enable && fWorkingSet.getSelection()) { + enableSpec= true; + } + fWorkingSetSpec.setEnabled(enableSpec); + fWorkingSetButton.setEnabled(enable); + } + } + + private CRenameProcessor getRenameProcessor() { + return (CRenameProcessor) ((CRenameRefactoring) getRefactoring()).getProcessor(); + } +} diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/rename/CRenameRefactoringWizard.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/rename/CRenameRefactoringWizard.java new file mode 100644 index 00000000000..788ccd17074 --- /dev/null +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/rename/CRenameRefactoringWizard.java @@ -0,0 +1,31 @@ +/******************************************************************************* + * Copyright (c) 2004, 2008 Wind River Systems, Inc. and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Markus Schorn - initial API and implementation + ******************************************************************************/ +package org.eclipse.cdt.internal.ui.refactoring.rename; + +import org.eclipse.ltk.ui.refactoring.RefactoringWizard; + +/** + * Refactoring Wizard adding the input page. + */ +public class CRenameRefactoringWizard extends RefactoringWizard { + + public CRenameRefactoringWizard(CRenameRefactoring r) { + super(r, DIALOG_BASED_USER_INTERFACE); + } + + // overrider + @Override + protected void addUserInputPages() { + setDefaultPageTitle(getRefactoring().getName()); + CRenameRefactoringInputPage page= new CRenameRefactoringInputPage(); + addPage(page); + } +} diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/rename/CRenameTypeProcessor.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/rename/CRenameTypeProcessor.java new file mode 100644 index 00000000000..97c094a4590 --- /dev/null +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/rename/CRenameTypeProcessor.java @@ -0,0 +1,21 @@ +/******************************************************************************* + * Copyright (c) 2005, 2008 Wind River Systems, Inc. and others + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Markus Schorn - initial API and implementation + ******************************************************************************/ +package org.eclipse.cdt.internal.ui.refactoring.rename; + +/** + * Handles conflicting bindings for types. + */ +public class CRenameTypeProcessor extends CRenameGlobalProcessor { + + public CRenameTypeProcessor(CRenameProcessor processor, String kind) { + super(processor, kind); + } +} diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/rename/Messages.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/rename/Messages.java new file mode 100644 index 00000000000..63c3d6172ff --- /dev/null +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/rename/Messages.java @@ -0,0 +1,31 @@ +/******************************************************************************* + * Copyright (c) 2004, 2008 Wind River Systems, Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Markus Schorn - initial API and implementation + ******************************************************************************/ +package org.eclipse.cdt.internal.ui.refactoring.rename; + +import java.util.MissingResourceException; +import java.util.ResourceBundle; + +public class Messages { + private static final String BUNDLE_NAME = "org.eclipse.cdt.internal.ui.refactoring.rename.messages";//$NON-NLS-1$ + + private static final ResourceBundle RESOURCE_BUNDLE = ResourceBundle.getBundle(BUNDLE_NAME); + + private Messages() { + } + + public static String getString(String key) { + try { + return RESOURCE_BUNDLE.getString(key); + } catch (MissingResourceException e) { + return '!' + key + '!'; + } + } +} diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/rename/TextSearchWrapper.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/rename/TextSearchWrapper.java new file mode 100644 index 00000000000..7729ab88ff8 --- /dev/null +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/rename/TextSearchWrapper.java @@ -0,0 +1,363 @@ +/******************************************************************************* + * Copyright (c) 2004, 2008 Wind River Systems, Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Markus Schorn - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.ui.refactoring.rename; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.Reader; +import java.io.UnsupportedEncodingException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.Comparator; +import java.util.HashSet; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.resources.IResourceProxy; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IAdaptable; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.SubProgressMonitor; +import org.eclipse.search.core.text.TextSearchEngine; +import org.eclipse.search.core.text.TextSearchMatchAccess; +import org.eclipse.search.core.text.TextSearchRequestor; +import org.eclipse.search.core.text.TextSearchScope; +import org.eclipse.ui.IWorkingSet; +import org.eclipse.ui.IWorkingSetManager; +import org.eclipse.ui.PlatformUI; + +import org.eclipse.cdt.core.model.CoreModel; +import org.eclipse.cdt.core.model.ICElement; +import org.eclipse.cdt.core.model.ITranslationUnit; + +import org.eclipse.cdt.internal.formatter.scanner.SimpleScanner; +import org.eclipse.cdt.internal.formatter.scanner.Token; + + + +/** + * Wraps the platform text search and uses a scanner to categorize the text-matches + * by location (comments, string-literals, etc.). + */ +public class TextSearchWrapper { + public final static int SCOPE_FILE = 1; + public final static int SCOPE_WORKSPACE = 2; + public final static int SCOPE_RELATED_PROJECTS = 3; + public final static int SCOPE_SINGLE_PROJECT = 4; + public final static int SCOPE_WORKING_SET = 5; + + private static class SearchScope extends TextSearchScope { + public static SearchScope newSearchScope(IWorkingSet ws) { + IAdaptable[] adaptables= ws.getElements(); + ArrayList resources = new ArrayList(); + for (int i = 0; i < adaptables.length; i++) { + IAdaptable adaptable = adaptables[i]; + IResource r= (IResource) adaptable.getAdapter(IResource.class); + if (r != null) { + resources.add(r); + } + } + return newSearchScope(resources.toArray(new IResource[resources.size()]), false); + } + + public static SearchScope newSearchScope(IResource[] resources, boolean copy) { + return new SearchScope(resources, copy); + } + + private IResource[] fRootResources; + private ArrayList fFileMatcher= new ArrayList(); + + private SearchScope(IResource[] resources, boolean copy) { + fRootResources= copy ? (IResource[]) resources.clone() : resources; + } + + @Override + public IResource[] getRoots() { + return fRootResources; + } + + @Override + public boolean contains(IResourceProxy proxy) { + if (proxy.isDerived()) { + return false; + } + if (proxy.getType() == IResource.FILE) { + return containsFile(proxy.getName()); + } + return true; + } + + private boolean containsFile(String name) { + for (Iterator iter = fFileMatcher.iterator(); iter.hasNext();) { + Matcher matcher = iter.next(); + matcher.reset(name); + if (matcher.matches()) { + return true; + } + } + return false; + } + + public void addFileNamePattern(String filePattern) { + Pattern p= Pattern.compile(filePatternToRegex(filePattern)); + fFileMatcher.add(p.matcher("")); //$NON-NLS-1$ + } + + private String filePatternToRegex(String filePattern) { + StringBuffer result = new StringBuffer(); + for (int i = 0; i < filePattern.length(); i++) { + char c = filePattern.charAt(i); + switch(c) { + case '\\': + case '(': + case ')': + case '{': + case '}': + case '.': + case '[': + case ']': + case '$': + case '^': + case '+': + case '|': + result.append('\\'); + result.append(c); + break; + case '?': + result.append('.'); + break; + case '*': + result.append(".*"); //$NON-NLS-1$ + break; + default: + result.append(c); + break; + } + } + return result.toString(); + } + } + + public TextSearchWrapper() {} + + private TextSearchScope createSearchScope(IFile file, int scope, + String workingSetName, String[] patterns) { + switch (scope) { + case SCOPE_WORKSPACE: + return defineSearchScope(file.getWorkspace().getRoot(), patterns); + case SCOPE_SINGLE_PROJECT: + return defineSearchScope(file.getProject(), patterns); + case SCOPE_FILE: + return defineSearchScope(file, patterns); + case SCOPE_WORKING_SET: { + TextSearchScope result= defineWorkingSetAsSearchScope(workingSetName, patterns); + if (result == null) { + result= defineSearchScope(file.getWorkspace().getRoot(), patterns); + } + return result; + } + } + return defineRelatedProjectsAsSearchScope(file.getProject(), patterns); + } + + private TextSearchScope defineRelatedProjectsAsSearchScope(IProject project, String[] patterns) { + HashSet projects= new HashSet(); + LinkedList workThrough= new LinkedList(); + workThrough.add(project); + while (!workThrough.isEmpty()) { + IProject prj= workThrough.removeLast(); + if (projects.add(prj)) { + try { + workThrough.addAll(Arrays.asList(prj.getReferencedProjects())); + workThrough.addAll(Arrays.asList(prj.getReferencingProjects())); + } catch (CoreException e) { + // need to ignore + } + } + } + IResource[] resources= projects.toArray(new IResource[projects.size()]); + return defineSearchScope(resources, patterns); + } + + private TextSearchScope defineWorkingSetAsSearchScope(String wsName, String[] patterns) { + if (wsName == null) { + return null; + } + IWorkingSetManager wsManager= PlatformUI.getWorkbench().getWorkingSetManager(); + IWorkingSet ws= wsManager.getWorkingSet(wsName); + if (ws == null) { + return null; + } + SearchScope result= SearchScope.newSearchScope(ws); + applyFilePatterns(result, patterns); + return result; + } + + private void applyFilePatterns(SearchScope scope, String[] patterns) { + for (int i = 0; i < patterns.length; i++) { + String pattern = patterns[i]; + scope.addFileNamePattern(pattern); + } + } + + private TextSearchScope defineSearchScope(IResource resource, String[] patterns) { + SearchScope result= SearchScope.newSearchScope(new IResource[]{resource}, false); + applyFilePatterns(result, patterns); + return result; + } + + private TextSearchScope defineSearchScope(IResource[] resources, String[] patterns) { + SearchScope result= SearchScope.newSearchScope(resources, true); + applyFilePatterns(result, patterns); + return result; + } + + /** + * @param monitor + */ + public IStatus searchWord(int scope, IFile resource, String workingSet, String[] patterns, + String word, IProgressMonitor monitor, final List target) { + int startPos= target.size(); + TextSearchEngine engine= TextSearchEngine.create(); + StringBuffer searchPattern= new StringBuffer(word.length()+ 8); + searchPattern.append("\\b"); //$NON-NLS-1$ + searchPattern.append("\\Q"); //$NON-NLS-1$ + searchPattern.append(word); + searchPattern.append("\\E"); //$NON-NLS-1$ + searchPattern.append("\\b"); //$NON-NLS-1$ + + Pattern pattern= Pattern.compile(searchPattern.toString()); + + TextSearchScope searchscope= createSearchScope(resource, scope, workingSet, patterns); + TextSearchRequestor requestor= new TextSearchRequestor() { + @Override + public boolean acceptPatternMatch(TextSearchMatchAccess access) { + IFile file= access.getFile(); + ICElement elem= CoreModel.getDefault().create(file); + if (elem instanceof ITranslationUnit) { + target.add(new CRefactoringMatch(file, + access.getMatchOffset(), access.getMatchLength(), 0)); + } + return true; + } + }; + IStatus result= engine.search(searchscope, requestor, pattern, + new SubProgressMonitor(monitor, 95)); + categorizeMatches(target.subList(startPos, target.size()), + new SubProgressMonitor(monitor, 5)); + + return result; + } + + public void categorizeMatches(List matches, IProgressMonitor monitor) { + monitor.beginTask(Messages.getString("TextSearch.monitor.categorizeMatches"), matches.size()); //$NON-NLS-1$ + IFile file= null; + ArrayList locations= null; + for (Iterator iter = matches.iterator(); iter.hasNext();) { + CRefactoringMatch match = iter.next(); + IFile tfile= match.getFile(); + if (file == null || !file.equals(tfile)) { + file= tfile; + locations= new ArrayList(); + computeLocations(file, locations); + } + match.setLocation(findLocation(match, locations)); + monitor.worked(1); + } + } + + final static Comparator COMPARE_FIRST_INTEGER= new Comparator() { + public int compare(int[] o1, int[] o2) { + return (o1)[0]-(o2)[0]; + } + }; + private int findLocation(CRefactoringMatch match, ArrayList states) { + int pos= Collections.binarySearch(states, new int[] {match.getOffset()}, COMPARE_FIRST_INTEGER); + if (pos<0) { + pos= -pos-2; + if (pos < 0) { + pos=0; + } + } + int endOffset= match.getOffset() + match.getLength(); + int location= 0; + while (pos= endOffset) { + break; + } + location |= info[1]; + pos++; + } + return location; + } + + private void computeLocations(IFile file, ArrayList locations) { + Reader reader; + SimpleScanner scanner= new SimpleScanner(); + try { + reader = new BufferedReader( + new InputStreamReader(file.getContents(), file.getCharset())); + } catch (CoreException e) { + return; + } catch (UnsupportedEncodingException e) { + return; + } + try { + scanner.initialize(reader, null); + scanner.setReuseToken(true); + Token token; + int lastState= 0; + while((token= scanner.nextToken()) != null) { + int state= CRefactory.OPTION_IN_CODE; + switch(token.getType()) { + case Token.tLINECOMMENT: + case Token.tBLOCKCOMMENT: + state= CRefactory.OPTION_IN_COMMENT; + break; + case Token.tSTRING: + case Token.tLSTRING: + case Token.tCHAR: + state= CRefactory.OPTION_IN_STRING_LITERAL; + break; + case Token.tPREPROCESSOR: + state= CRefactory.OPTION_IN_PREPROCESSOR_DIRECTIVE; + break; + case Token.tPREPROCESSOR_DEFINE: + state= CRefactory.OPTION_IN_MACRO_DEFINITION; + break; + case Token.tPREPROCESSOR_INCLUDE: + state= CRefactory.OPTION_IN_INCLUDE_DIRECTIVE; + break; + } + if (state != lastState) { + locations.add(new int[] {token.getOffset(), state}); + lastState= state; + } + } + } + finally { + try { + reader.close(); + } catch (IOException e1) { + } + } + } +} diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/rename/messages.properties b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/rename/messages.properties new file mode 100644 index 00000000000..d7c2b8f3225 --- /dev/null +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/rename/messages.properties @@ -0,0 +1,96 @@ +############################################################################### +# Copyright (c) 2005, 2008 IBM Corporation and others. +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Eclipse Public License v1.0 +# which accompanies this distribution, and is available at +# http://www.eclipse.org/legal/epl-v10.html +# +# Contributors: +# IBM Corporation - initial API and implementation +# Markus Schorn, Wind River Systems Inc. +############################################################################### +CRenameProcessorDelegate.wizard.title=Rename {0} ''{1}'' +CRenameProcessorDelegate.globalFunction=Global function +CRenameProcessorDelegate.fileStaticFunction=File static function +CRenameProcessorDelegate.type=Type +CRenameProcessorDelegate.namespace=Namespace +CRenameLocalProcessor.parameter=Parameter +CRenameTopProcessor.wizard.title=Rename ''{0}'' +CRenameTopProcessor.localVar=local variable +CRenameLocalProcessor.method=Method +CRenameTopProcessor.parameter=parameter +CRenameTopProcessor.filelocalVar=file-local variable +CRenameLocalProcessor.enumerator=Enumerator +CRenameTopProcessor.globalVar=global variable +CRenameTopProcessor.field=field +CRenameTopProcessor.enumerator=enumerator +CRenameTopProcessor.globalFunction=global function +CRenameLocalProcessor.error.shadow=Shadowing +CRenameLocalProcessor.error.conflict=Name conflict +CRenameLocalProcessor.localVariable=Local variable +CRefactoringMatch.label.occurrence=Rename occurrence +CRefactoringMatch.label.comment=Rename in comment +CRenameTopProcessor.virtualMethod=virtual method +CRenameLocalProcessor.constructor=Constructor +CRenameTopProcessor.method=method +CRenameLocalProcessor.field=Field +CRenameTopProcessor.type=type +CRenameTopProcessor.namespace=namespace +CRenameTopProcessor.macro=macro +CRefactory.title.rename=Rename +CRenameProcessorDelegate.task.createChange=creating changes +CRenameProcessorDelegate.fileStaticVariable=File static variable +CRenameLocalProcessor.error.isShadowed=Shadowing +CRenameLocalProcessor.error.overloads=Overloading +CRenameProcessorDelegate.task.checkFinalCondition=Checking final conditions +CRenameProcessorDelegate.warning.potentialMatch.singular=Refactoring contains 1 potential match. +CRenameProcessorDelegate.warning.potentialMatch.plural=Refactoring contains {0} potential matches. +CRenameProcessorDelegate.warning.commentMatch.singular=Refactoring contains 1 match within a comment. +CRenameProcessorDelegate.warning.commentMatch.plural=Refactoring contains {0} matches within comments. +CRenameTopProcessor.wizard.backup.title=Rename +CRenameTopProcessor.filelocalFunction=file local function +CRenameLocalProcessor.error.redeclare=Redeclaration +CRenameLocalProcessor.globalVariable=Global variable +CRenameIncludeProcessor.includeDirective=include directive +CRenameTopProcessor.error.renameWithoutSourceFile=No source +CRenameTopProcessor.error.invalidTextSelection=The selected name could not be analyzed. +CRenameTopProcessor.error.invalidName=The selected name cannot be renamed. +TextSearch.monitor.categorizeMatches=categorizing matches +CRenameRefactoringInputPage.newIdentifier.label=Rename to: +CRenameRefactoringInputPage.button.scope.workspace=all projects +CRenameRefactoringInputPage.errorInvalidIdentifier=''{0}'' is not a valid identifier +CRenameMethodProcessor.fatalError.renameDestructor=Destructor cannot be renamed! +CRenameRefactoringInputPage.button.scope.releatedprojects=related projects +CRenameRefactoringInputPage.button.singleProject=project +CRenameMethodProcessor.fatalError.renameOperator=Operators cannot be renamed! +CRenameMethodProcessor.warning.illegalCharacters=Name contains illegal characters! +CRenameRefactoringInputPage.button.workingSet=working set: +CRenameRefactoringInputPage.button.chooseWorkingSet=Choose... +CRenameRefactoringInputPage.update.label=source code +CRenameRefactoringInputPage.label.scope=Scope of refactoring: +CRenameRefactoringInputPage.button.inactiveCode=inactive conditional compilation code branches +CRenameRefactoringInputPage.button.comments=comments +CRenameRefactoringInputPage.button.strings=string literals +#140078 +CRenameLocalProcessor.error.message=A conflict was encountered during refactoring. +CRenameLocalProcessor.error.message1=Type of problem: {0} +CRenameLocalProcessor.error.message2=New element: {0} +CRenameLocalProcessor.error.message3=Conflicting element type: {0} +#140078 +CRenameRefactoringInputPage.button.macrodefinitions=macro definitions +CRenameMethodProcessor.fatalError.renameConstructor=Constructor cannot be renamed! +CRenameMethodProcessor.fatalError.renameToConstructor=Cannot rename method to constructor! +CRenameMethodProcessor.fatalError.renameToDestructor=Cannot rename method to destructor! +CRenameRefactoringInputPage.button.includes=include directives +CRefactoringMatch.label.potentialOccurrence=Rename potential occurrence +CRenameMethodProcessor.warning.renameVirtual=Renaming a virtual method. Consider renaming the base and derived class methods (if any). +CRenameRefactoringInputPage.button.preprocessor=other preprocessor directives +CRenameRefactoringInputPage.label.updateWithin=Update within: +ASTManager.task.analyze=Analyzing source code +ASTManager.task.generateAst=Generating AST +ASTManager.subtask.analyzing=Analyzing {0} files +ASTManager.warning.parsingError=Parsing error +ASTManager.warning.parsingError.detailed=Parsing error - {0} - +ASTManager.warning.parsingError.withFile={0} in file ''{1}'' +ASTManager.warning.parsingError.withFileAndLine={0} in file ''{1}'' at line ''{2}'' +ASTManager.error.macro.name.conflict=''{0}'' conflicts with the name of an existing macro! diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/utils/EclipseObjects.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/utils/EclipseObjects.java new file mode 100644 index 00000000000..44122485176 --- /dev/null +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/utils/EclipseObjects.java @@ -0,0 +1,145 @@ +/******************************************************************************* + * Copyright (c) 2008 Institute for Software, HSR Hochschule fuer Technik + * Rapperswil, University of applied sciences and others + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Institute for Software - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.ui.refactoring.utils; + +import org.eclipse.cdt.core.dom.ast.IASTNode; +import org.eclipse.cdt.core.model.ICElement; +import org.eclipse.cdt.internal.ui.editor.CEditor; +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.resources.ResourcesPlugin; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.Path; +import org.eclipse.jface.text.IDocument; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.ui.IEditorInput; +import org.eclipse.ui.IEditorPart; +import org.eclipse.ui.IEditorReference; +import org.eclipse.ui.IFileEditorInput; +import org.eclipse.ui.IWorkbenchPage; +import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.editors.text.TextEditor; +import org.eclipse.ui.texteditor.IDocumentProvider; +import org.eclipse.ui.texteditor.ITextEditor; + +public class EclipseObjects { + static public IWorkbenchPage getActivePage() { + return PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage(); + } + + static public IEditorPart getActiveEditor() { + IEditorPart editor = null; + + IWorkbenchPage page = getActivePage(); + + if (page.isEditorAreaVisible() + && page.getActiveEditor() != null + && page.getActiveEditor() instanceof TextEditor) { + editor = page.getActiveEditor(); + } + return editor; + } + + static public IEditorPart getEditorForFile(IFile file) { + IWorkbenchPage page = getActivePage(); + IEditorReference[] editors = page.getEditorReferences(); + for (int i = 0; i < editors.length; i++) { + IEditorPart editor = editors[i].getEditor(false); + if (editor instanceof CEditor) { + CEditor edi = ((CEditor)editor); + IResource resource = edi.getInputCElement().getResource(); + if (resource instanceof IFile) { + if( (( IFile )resource).equals(file) ){ + return editor; + } + } + + } + } + return null; + } + + static public IFile getActiveFile(){ + IEditorInput edi = getActiveEditor().getEditorInput(); + + IFile aFile = null; + if(edi instanceof IFileEditorInput){ + aFile = ((IFileEditorInput)edi).getFile(); + } + + return aFile; + } + + static public IDocument getActiveDocument() { + return getDocument( getActiveEditor() ); + } + + static public IDocument getDocument() { + ITextEditor txtEditor = ((ITextEditor)getActiveEditor()); + if(txtEditor == null) + return null; + IDocumentProvider prov = txtEditor.getDocumentProvider(); + return prov.getDocument(txtEditor.getEditorInput()); + } + + static public IDocument getDocument(IEditorPart editor) { + ITextEditor txtEditor = ((ITextEditor)editor); + IDocumentProvider prov = txtEditor.getDocumentProvider(); + return prov.getDocument(txtEditor.getEditorInput()); + } + + public static IWorkbenchWindow getActiveWindow() { + return PlatformUI.getWorkbench().getActiveWorkbenchWindow(); + } + + public static IDocument getDocument(IFile file) { + IEditorPart editor = getEditorForFile(file); + return getDocument(editor); + } + + static public IFile getFile(ISelection selection) { + if (selection instanceof IStructuredSelection && !selection.isEmpty()) { + IFile file = getFile((IStructuredSelection)selection); + return file; + } else { + return EclipseObjects.getActiveFile(); + } + } + + static private IFile getFile(IStructuredSelection selection) { + IFile file = null; + Object o = selection.getFirstElement(); + + if (o instanceof ICElement) { + ICElement e= (ICElement) o; + IResource r= e.getUnderlyingResource(); + if (r instanceof IFile) { + file= (IFile) r; + } + } + + return file; + } + + public static IFile getFileForPathString(String path) { + IPath ipath = new Path(path); + return ResourcesPlugin.getWorkspace().getRoot().getFileForLocation(ipath); + } + + public static IFile getFile(IASTNode node){ + if(node == null) + return null; + return getFileForPathString(node.getFileLocation().getFileName()); + } +} diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/utils/FileContentHelper.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/utils/FileContentHelper.java new file mode 100644 index 00000000000..eb59d5b5198 --- /dev/null +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/utils/FileContentHelper.java @@ -0,0 +1,101 @@ +/******************************************************************************* + * Copyright (c) 2008 Institute for Software, HSR Hochschule fuer Technik + * Rapperswil, University of applied sciences and others + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Institute for Software - initial API and implementation + ******************************************************************************/ +package org.eclipse.cdt.internal.ui.refactoring.utils; + +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.UnsupportedEncodingException; + +import org.eclipse.core.resources.IFile; +import org.eclipse.core.runtime.CoreException; + +import org.eclipse.cdt.ui.CUIPlugin; + +/** + * @author Emanuel Graf IFS + * + */ +public class FileContentHelper { + + private static final int bufferSize = 512; + + public static String getContent(IFile file, int start) throws CoreException, IOException{ + + InputStreamReader reader = getReaderForFile(file); + skip(start, reader); + + return readRest(reader); + + } + + public static String getContent(IFile file, int start, int length) { + try { + InputStreamReader r = getReaderForFile(file); + char[] bytes = new char[length]; + + skip(start, r); + + read(length, r, bytes); + + return new String(bytes); + } catch (IOException e) { + CUIPlugin.getDefault().log(e); + } catch (CoreException e) { + CUIPlugin.getDefault().log(e); + } + return ""; //$NON-NLS-1$ + } + + private static InputStreamReader getReaderForFile(IFile file) + throws CoreException, UnsupportedEncodingException { + InputStream contents = file.getContents(); + InputStreamReader r = new InputStreamReader(contents, file.getCharset()); + return r; + } + + private static String readRest(InputStreamReader reader) throws IOException{ + StringBuilder content = new StringBuilder(); + char[] buffer = new char[bufferSize]; + int bytesRead = 0; + while((bytesRead = reader.read(buffer)) >= 0){ + content.append(buffer, 0, bytesRead); + } + + + return content.toString(); + } + + private static void read(int length, InputStreamReader r, char[] bytes) + throws IOException { + int bufferOffset = 0; + int charactersRead = 0; + while(charactersRead >= 0 && length > 0){ + charactersRead = r.read(bytes, bufferOffset, length); + if(charactersRead > 0){ + bufferOffset += charactersRead; + length -= charactersRead; + } + } + } + + private static void skip(int start, InputStreamReader r) throws IOException { + long skipped = 0; + while(skipped >= 0 && start > 0 && r.ready()){ + skipped = r.skip(start); + if(skipped > 0){ + start -= skipped; + } + } + } + +} diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/utils/FileHelper.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/utils/FileHelper.java new file mode 100644 index 00000000000..ace50f12194 --- /dev/null +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/utils/FileHelper.java @@ -0,0 +1,77 @@ +/******************************************************************************* + * Copyright (c) 2008 Institute for Software, HSR Hochschule fuer Technik + * Rapperswil, University of applied sciences and others + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Institute for Software - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.ui.refactoring.utils; + +import java.io.IOException; +import java.io.InputStream; + +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.ProjectScope; +import org.eclipse.core.resources.ResourcesPlugin; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.Path; +import org.eclipse.core.runtime.Platform; +import org.eclipse.core.runtime.preferences.IScopeContext; +import org.eclipse.core.runtime.preferences.InstanceScope; +import org.eclipse.jface.text.TextUtilities; + +import org.eclipse.cdt.core.dom.ast.IASTFileLocation; +import org.eclipse.cdt.core.dom.ast.IASTNode; + +public class FileHelper { + + private static final String DEFAULT_LINE_DELIMITTER = "\n"; //$NON-NLS-1$ + + public static IFile getIFilefromIASTNode(IASTNode node) { + IPath implPath = new Path(node.getContainingFilename()); + return ResourcesPlugin.getWorkspace().getRoot().getFileForLocation(implPath); + } + + public static boolean isFirstWithinSecondLocation(IASTFileLocation loc1, IASTFileLocation loc2){ + + boolean isEquals = true; + + isEquals &= loc1.getFileName().equals(loc2.getFileName()); + isEquals &= loc1.getNodeOffset() >= loc2.getNodeOffset(); + isEquals &= loc1.getNodeOffset()+loc1.getNodeLength() <= loc2.getNodeOffset() + loc2.getNodeLength(); + + return isEquals; + } + + public static String determineLineDelimiter(IFile file) { + StringBuilder fileContent = new StringBuilder(); + try { + InputStream fis = file.getContents(); + byte[] buffer = new byte[1024]; + int read; + while ((read = fis.read(buffer)) >= 0) + fileContent.append(new String(buffer, 0, read)); + } catch (CoreException e) { + } catch (IOException e) { + } catch (NullPointerException e){ + } + + IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject(); + IScopeContext[] scopeContext; + if(project != null){ + scopeContext = new IScopeContext[] { new ProjectScope(project)}; + } + else{ + scopeContext = new IScopeContext[] { new InstanceScope()}; + } + String platformDefaultLineDelimiter = System.getProperty("line.separator", DEFAULT_LINE_DELIMITTER); //$NON-NLS-1$ + String defaultLineDelimiter = Platform.getPreferencesService().getString(Platform.PI_RUNTIME, Platform.PREF_LINE_SEPARATOR, platformDefaultLineDelimiter, scopeContext); + return TextUtilities.determineLineDelimiter(fileContent.toString(), defaultLineDelimiter); + } +} diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/utils/IdentifierHelper.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/utils/IdentifierHelper.java new file mode 100644 index 00000000000..f9aabee1803 --- /dev/null +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/utils/IdentifierHelper.java @@ -0,0 +1,85 @@ +/******************************************************************************* + * Copyright (c) 2008 Institute for Software, HSR Hochschule fuer Technik + * Rapperswil, University of applied sciences and others + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Institute for Software - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.ui.refactoring.utils; + +import java.util.Set; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import org.eclipse.cdt.core.parser.KeywordSetKey; +import org.eclipse.cdt.core.parser.ParserLanguage; +import org.eclipse.cdt.internal.core.parser.token.KeywordSets; + +/** + * @author Thomas Corbat + * + */ +public class IdentifierHelper { + + private static final String QUOTE = Messages.IdentifierHelper_quote; + + public static IdentifierResult checkIdentifierName(String identifier){ + + if(identifier == null){ + return null; + } + if(isCorrect(identifier)){ + if(isKeyword(identifier)){ + return new IdentifierResult(IdentifierResult.KEYWORD, QUOTE + identifier + Messages.IdentifierHelper_isKeyword); + } + else{ + return new IdentifierResult(IdentifierResult.VALID, QUOTE + identifier + Messages.IdentifierHelper_isValid ); + } + } else if(isLeadingADigit(identifier)){ + return new IdentifierResult(IdentifierResult.DIGIT_FIRST, QUOTE + identifier + Messages.IdentifierHelper_leadingDigit); + } else if(identifier.length() == 0){ + return new IdentifierResult(IdentifierResult.EMPTY, Messages.IdentifierHelper_emptyIdentifier ); + } else if(hasIllegalCharacters(identifier)){ + return new IdentifierResult(IdentifierResult.ILLEGAL_CHARACTER, Messages.IdentifierHelper_illegalCharacter + identifier + QUOTE); + } + + return new IdentifierResult(IdentifierResult.UNKNOWN, QUOTE + identifier + Messages.IdentifierHelper_unidentifiedMistake); + } + + private static boolean isKeyword(String identifier) { + + for(String currentKeyword : getKeywords()){ + if(identifier.equals(currentKeyword)){ + return true; + } + } + return false; + } + + private static boolean hasIllegalCharacters(String identifier) { + Pattern p = Pattern.compile("\\W"); //$NON-NLS-1$ + Matcher m = p.matcher(identifier); + return m.find(); + } + + private static boolean isLeadingADigit(String identifier) { + Pattern p = Pattern.compile("\\d.*"); //$NON-NLS-1$ + Matcher m = p.matcher(identifier); + return m.matches(); + } + + private static boolean isCorrect(String identifier) { + Pattern p = Pattern.compile("[a-zA-Z_]\\w*"); //$NON-NLS-1$ + Matcher m = p.matcher(identifier); + return m.matches(); + } + + public static String[] getKeywords() { + Set keywords= KeywordSets.getKeywords(KeywordSetKey.KEYWORDS, ParserLanguage.CPP); + return keywords.toArray(new String[keywords.size()]); + } +} diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/utils/IdentifierResult.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/utils/IdentifierResult.java new file mode 100644 index 00000000000..8310ef5733a --- /dev/null +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/utils/IdentifierResult.java @@ -0,0 +1,49 @@ +/******************************************************************************* + * Copyright (c) 2008 Institute for Software, HSR Hochschule fuer Technik + * Rapperswil, University of applied sciences and others + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Institute for Software - initial API and implementation + *******************************************************************************/ + +package org.eclipse.cdt.internal.ui.refactoring.utils; + + +/** + * @author Thomas Corbat + * + */ +public class IdentifierResult { + + public static final int VALID = 0; + public static final int EMPTY = 1; + public static final int ILLEGAL_CHARACTER = 2; + public static final int DIGIT_FIRST = 3; + public static final int KEYWORD = 4; + public static final int UNKNOWN = 5; + + + private int result; + private String message; + + public boolean isCorrect(){ + return result == VALID; + } + + public int getResult(){ + return result; + } + + public String getMessage(){ + return message; + } + + public IdentifierResult(int result, String message) { + this.result = result; + this.message = message; + } +} diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/utils/Messages.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/utils/Messages.java new file mode 100644 index 00000000000..8c650372931 --- /dev/null +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/utils/Messages.java @@ -0,0 +1,39 @@ +/******************************************************************************* + * Copyright (c) 2008 Institute for Software, HSR Hochschule fuer Technik + * Rapperswil, University of applied sciences and others + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Institute for Software - initial API and implementation + *******************************************************************************/ + +package org.eclipse.cdt.internal.ui.refactoring.utils; + +import org.eclipse.osgi.util.NLS; + +public final class Messages extends NLS { + + private static final String BUNDLE_NAME = "org.eclipse.cdt.internal.ui.refactoring.utils.messages";//$NON-NLS-1$ + + private Messages() { + // Do not instantiate + } + + public static String IdentifierHelper_isKeyword; + public static String IdentifierHelper_isValid; + public static String IdentifierHelper_quote; + public static String IdentifierHelper_leadingDigit; + public static String IdentifierHelper_emptyIdentifier; + public static String IdentifierHelper_illegalCharacter; + public static String IdentifierHelper_unidentifiedMistake; + public static String VisibilityEnum_public; + public static String VisibilityEnum_protected; + public static String VisibilityEnum_private; + + static { + NLS.initializeMessages(BUNDLE_NAME, Messages.class); + } +} diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/utils/OffsetHelper.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/utils/OffsetHelper.java new file mode 100644 index 00000000000..1eb704c2843 --- /dev/null +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/utils/OffsetHelper.java @@ -0,0 +1,97 @@ +/******************************************************************************* + * Copyright (c) 2008 Institute for Software, HSR Hochschule fuer Technik + * Rapperswil, University of applied sciences and others + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Institute for Software - initial API and implementation + ******************************************************************************/ +package org.eclipse.cdt.internal.ui.refactoring.utils; + +import org.eclipse.cdt.core.dom.ast.IASTFileLocation; +import org.eclipse.cdt.core.dom.ast.IASTMacroExpansionLocation; +import org.eclipse.cdt.core.dom.ast.IASTNode; +import org.eclipse.cdt.core.dom.ast.IASTNodeLocation; +import org.eclipse.cdt.internal.core.dom.parser.ASTNode; + +/** + * @author Emanuel Graf IFS + * + */ +public class OffsetHelper { + + public static int getOffsetIncludingComment(IASTNode node) { + int nodeStart = Integer.MAX_VALUE; + IASTNodeLocation[] nodeLocations = node.getNodeLocations(); + if (nodeLocations.length != 1) { + int offset; + for (IASTNodeLocation location : nodeLocations) { + if (location instanceof IASTMacroExpansionLocation) { + IASTMacroExpansionLocation macroLoc = (IASTMacroExpansionLocation) location; + offset = macroLoc.asFileLocation().getNodeOffset(); + }else { + offset = location.asFileLocation().getNodeOffset(); + } + if(offset < nodeStart) nodeStart = offset; + } + } else { + nodeStart = node.getFileLocation().getNodeOffset(); + } + + return nodeStart; + } + + public static int getEndOffsetIncludingComments(IASTNode node) { + int fileOffset = 0; + int length = 0; + + IASTNodeLocation[] nodeLocations = node.getNodeLocations(); + if (nodeLocations.length != 1) { + for (IASTNodeLocation location : nodeLocations) { + if (location instanceof IASTMacroExpansionLocation) { + IASTMacroExpansionLocation macroLoc = (IASTMacroExpansionLocation) location; + fileOffset = macroLoc.asFileLocation().getNodeOffset(); + length = macroLoc.asFileLocation().getNodeLength(); + }else { + fileOffset = location.asFileLocation().getNodeOffset(); + length = location.asFileLocation().getNodeLength(); + } + } + } else { + IASTFileLocation loc = node.getFileLocation(); + + fileOffset = loc.getNodeOffset(); + length = loc.getNodeLength(); + } + return fileOffset + length; + + } + + public static int getEndOffsetWithoutComments(IASTNode node) { + return node.getFileLocation().getNodeOffset() + node.getFileLocation().getNodeLength(); + } + + public static int getLengthIncludingComment(IASTNode node) { + return OffsetHelper.getEndOffsetIncludingComments(node) - OffsetHelper.getOffsetIncludingComment(node); + } + + public static int getNodeOffset(ASTNode node) { + return node.getOffset(); + } + + public static int getNodeEndPoint(ASTNode node) { + return node.getOffset() + node.getLength(); + } + + public static int getStartingLineNumber(IASTNode node) { + return node.getFileLocation().getStartingLineNumber(); + } + + public static int getEndingLineNumber(IASTNode node) { + return node.getFileLocation().getEndingLineNumber(); + } + +} diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/utils/TranslationUnitHelper.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/utils/TranslationUnitHelper.java new file mode 100644 index 00000000000..af29081800b --- /dev/null +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/utils/TranslationUnitHelper.java @@ -0,0 +1,92 @@ +/******************************************************************************* + * Copyright (c) 2008 Institute for Software, HSR Hochschule fuer Technik + * Rapperswil, University of applied sciences and others + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Institute for Software - initial API and implementation + *******************************************************************************/ + +package org.eclipse.cdt.internal.ui.refactoring.utils; + +import org.eclipse.cdt.core.dom.CDOM; +import org.eclipse.cdt.core.dom.IASTServiceProvider.UnsupportedDialectException; +import org.eclipse.cdt.core.dom.ast.IASTDeclaration; +import org.eclipse.cdt.core.dom.ast.IASTFileLocation; +import org.eclipse.cdt.core.dom.ast.IASTName; +import org.eclipse.cdt.core.dom.ast.IASTNode; +import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit; +import org.eclipse.cdt.core.dom.ast.cpp.CPPASTVisitor; +import org.eclipse.cdt.internal.ui.refactoring.Container; +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.ResourcesPlugin; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.Path; + +public class TranslationUnitHelper { + + public static IASTTranslationUnit loadTranslationUnit(String filename) { + + if (filename != null) { + IPath path = new Path(filename); + IFile tmpFile = ResourcesPlugin.getWorkspace().getRoot().getFileForLocation(path); + return loadTranslationUnit(tmpFile); + } + + return null; + } + + public static IASTTranslationUnit loadTranslationUnit(IFile tmpFile) { + if (tmpFile != null) { + try { + IASTTranslationUnit fileUnit = CDOM.getInstance().getTranslationUnit(tmpFile, CDOM.getInstance().getCodeReaderFactory(CDOM.PARSE_SAVED_RESOURCES), true); + return fileUnit; + } catch (UnsupportedDialectException e) { + return null; + } + } + return null; + } + + public static IASTName findNameInTranslationUnit(IASTTranslationUnit transUnit, IASTNode oldName) { + final String oldFileName = oldName.getFileLocation().getFileName(); + final IASTFileLocation pos = oldName.getFileLocation(); + final Container nameCon = new Container(); + + transUnit.accept(new CPPASTVisitor() { + + { + shouldVisitNames = true; + } + + @Override + public int visit(IASTName locName) { + IASTFileLocation locFileLocation = locName.getFileLocation(); + if (locFileLocation != null && oldFileName.equals(locFileLocation.getFileName()) && pos.getNodeOffset() == locFileLocation.getNodeOffset() + && pos.getNodeLength() == locFileLocation.getNodeLength()) { + nameCon.setObject(locName); + return PROCESS_ABORT; + } + return super.visit(locName); + } + + }); + return nameCon.getObject(); + } + + public static IASTNode getFirstNode(IASTTranslationUnit unit) { + IASTDeclaration firstNode = null; + for (IASTDeclaration each : unit.getDeclarations()) { + if(firstNode == null) { + firstNode = each; + } else if(each.getNodeLocations() != null && + each.getNodeLocations()[0].getNodeOffset() < firstNode.getNodeLocations()[0].getNodeOffset()) { + firstNode = each; + } + } + return firstNode; + } +} diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/utils/VisibilityEnum.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/utils/VisibilityEnum.java new file mode 100644 index 00000000000..54331504340 --- /dev/null +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/utils/VisibilityEnum.java @@ -0,0 +1,80 @@ +/******************************************************************************* + * Copyright (c) 2008 Institute for Software, HSR Hochschule fuer Technik + * Rapperswil, University of applied sciences and others + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Institute for Software - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.ui.refactoring.utils; + +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTVisiblityLabel; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier; + +public enum VisibilityEnum { + + v_public(Messages.VisibilityEnum_public), + v_protected(Messages.VisibilityEnum_protected), + v_private(Messages.VisibilityEnum_private); + + private final String stringRepresentation; + + VisibilityEnum(String stringRepresentation) { + this.stringRepresentation = stringRepresentation; + } + + public static VisibilityEnum from(ICPPASTVisiblityLabel visibility) { + switch(visibility.getVisibility()){ + case ICPPASTVisiblityLabel.v_private: + return VisibilityEnum.v_private; + case ICPPASTVisiblityLabel.v_protected: + return VisibilityEnum.v_protected; + case ICPPASTVisiblityLabel.v_public: + return VisibilityEnum.v_public; + } + return null; + } + + public int getASTBaseSpecifierVisibility() { + switch (this) { + case v_private: + return ICPPASTBaseSpecifier.v_private; + case v_protected: + return ICPPASTBaseSpecifier.v_protected; + case v_public: + return ICPPASTBaseSpecifier.v_public; + } + return 0; + } + + public int getICPPASTVisiblityLabelVisibility() { + switch (this) { + case v_private: + return ICPPASTVisiblityLabel.v_private; + case v_protected: + return ICPPASTVisiblityLabel.v_protected; + case v_public: + return ICPPASTVisiblityLabel.v_public; + } + return 0; + } + + public static VisibilityEnum getEnumForStringRepresentation(String visibility){ + if( VisibilityEnum.v_private.toString().equals( visibility ) ) { + return VisibilityEnum.v_private; + }else if( VisibilityEnum.v_protected.toString().equals( visibility ) ) { + return VisibilityEnum.v_protected; + }else if ( VisibilityEnum.v_public.toString().equals( visibility ) ) { + return VisibilityEnum.v_public; + } + return null; + } + + @Override + public String toString() { + return stringRepresentation; + } +} diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/utils/messages.properties b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/utils/messages.properties new file mode 100644 index 00000000000..2e7dd7f0872 --- /dev/null +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/utils/messages.properties @@ -0,0 +1,21 @@ +############################################################################### +# Copyright (c) 2008 Institute for Software, HSR Hochschule fuer Technik +# Rapperswil, University of applied sciences and others +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Eclipse Public License v1.0 +# which accompanies this distribution, and is available at +# http://www.eclipse.org/legal/epl-v10.html +# +# Contributors: +# Institute for Software - initial API and implementation +############################################################################### +IdentifierHelper_isKeyword=' is a keyword. +IdentifierHelper_isValid=' is valid. +IdentifierHelper_quote=' +IdentifierHelper_leadingDigit=' has a leading digit. +IdentifierHelper_emptyIdentifier=Identifier must not be empty. +IdentifierHelper_illegalCharacter="Illegal character found in ' +IdentifierHelper_unidentifiedMistake=' contains an unidentified mistake. +VisibilityEnum_public=public +VisibilityEnum_protected=protected +VisibilityEnum_private=private diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/typehierarchy/Messages.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/typehierarchy/Messages.java index 62e23bcdd12..13c23c77020 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/typehierarchy/Messages.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/typehierarchy/Messages.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2007 Wind River Systems, Inc. and others. + * Copyright (c) 2007, 2008 Wind River Systems, Inc. and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -8,7 +8,6 @@ * Contributors: * Markus Schorn - initial API and implementation *******************************************************************************/ - package org.eclipse.cdt.internal.ui.typehierarchy; import org.eclipse.osgi.util.NLS; @@ -22,7 +21,6 @@ public class Messages extends NLS { public static String OpenTypeInHierarchyAction_message; public static String OpenTypeInHierarchyAction_title; public static String OpenTypeInHierarchyAction_upperListLabel; - public static String THGraph_error_elementNotFound; public static String THHierarchyModel_errorComputingHierarchy; public static String THHierarchyModel_Job_title; public static String THHistoryDropDownAction_ClearHistory; @@ -65,7 +63,6 @@ public class Messages extends NLS { public static String THViewPart_VerticalOrientation; public static String TypeHierarchyUI_OpenFailure_message; public static String TypeHierarchyUI_OpenTypeHierarchy; - public static String TypeHierarchyUI_SelectFromList; static { // initialize resource bundle NLS.initializeMessages(BUNDLE_NAME, Messages.class); diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/typehierarchy/THViewPart.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/typehierarchy/THViewPart.java index 9cdf187d82f..e0acf1ffdca 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/typehierarchy/THViewPart.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/typehierarchy/THViewPart.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2007 Wind River Systems, Inc. and others. + * Copyright (c) 2007, 2008 Wind River Systems, Inc. and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -8,7 +8,6 @@ * Contributors: * Markus Schorn - initial API and implementation *******************************************************************************/ - package org.eclipse.cdt.internal.ui.typehierarchy; import java.util.ArrayList; @@ -79,9 +78,9 @@ import org.eclipse.cdt.core.model.IMember; import org.eclipse.cdt.core.model.IMethodDeclaration; import org.eclipse.cdt.core.model.util.CElementBaseLabels; import org.eclipse.cdt.core.parser.ast.ASTAccessVisibility; -import org.eclipse.cdt.refactoring.actions.CRefactoringActionGroup; import org.eclipse.cdt.ui.CUIPlugin; import org.eclipse.cdt.ui.actions.OpenViewActionGroup; +import org.eclipse.cdt.ui.refactoring.actions.CRefactoringActionGroup; import org.eclipse.cdt.internal.ui.CPluginImages; import org.eclipse.cdt.internal.ui.IContextMenuConstants; @@ -127,7 +126,7 @@ public class THViewPart extends ViewPart implements ITHModelPresenter { private boolean fShowsMessage= true; private int fCurrentViewOrientation= -1; private boolean fInComputeOrientation= false; - private ArrayList fHistoryEntries= new ArrayList(MAX_HISTORY_SIZE); + private ArrayList fHistoryEntries= new ArrayList(MAX_HISTORY_SIZE); private int fIgnoreSelectionChanges= 0; // widgets @@ -180,7 +179,8 @@ public class THViewPart extends ViewPart implements ITHModelPresenter { private CRefactoringActionGroup fRefactoringActionGroup; private IContextActivation fContextActivation; - public void setFocus() { + @Override + public void setFocus() { fPagebook.setFocus(); } @@ -210,6 +210,7 @@ public class THViewPart extends ViewPart implements ITHModelPresenter { fModel.computeGraph(); } + @Override public void createPartControl(Composite parent) { fPagebook = new PageBook(parent, SWT.NULL); fPagebook.setLayoutData(new GridData(GridData.FILL_BOTH)); @@ -231,6 +232,7 @@ public class THViewPart extends ViewPart implements ITHModelPresenter { } } + @Override public void dispose() { if (fContextActivation != null) { IContextService ctxService = (IContextService)getSite().getService(IContextService.class); @@ -316,13 +318,15 @@ public class THViewPart extends ViewPart implements ITHModelPresenter { fMemberToolbarManager.update(true); } + @Override public void init(IViewSite site, IMemento memento) throws PartInitException { fMemento= memento; super.init(site, memento); } - public void saveState(IMemento memento) { + @Override + public void saveState(IMemento memento) { if (fWorkingSetFilterUI != null) { fWorkingSetFilterUI.saveState(memento, KEY_WORKING_SET_FILTER); } @@ -382,6 +386,7 @@ public class THViewPart extends ViewPart implements ITHModelPresenter { CElementLabels.getTextLabel(elem, CElementBaseLabels.ALL_FULLY_QUALIFIED | CElementBaseLabels.M_PARAMETER_TYPES) }); menu.appendToGroup(IContextMenuConstants.GROUP_OPEN, new Action(label) { + @Override public void run() { setInput(elem, null); } @@ -443,7 +448,8 @@ public class THViewPart extends ViewPart implements ITHModelPresenter { } }); fMemberViewer.setSorter(new ViewerSorter() { - public int category(Object element) { + @Override + public int category(Object element) { if (element instanceof ICElement) { ICElement celem= (ICElement)element; switch (celem.getElementType()) { @@ -534,15 +540,18 @@ public class THViewPart extends ViewPart implements ITHModelPresenter { fRefactoringActionGroup= new CRefactoringActionGroup(this); fWorkingSetFilterUI= new WorkingSetFilterUI(this, fMemento, KEY_WORKING_SET_FILTER) { - protected void onWorkingSetChange() { + @Override + protected void onWorkingSetChange() { updateWorkingSetFilter(this); } - protected void onWorkingSetNameChange() { + @Override + protected void onWorkingSetNameChange() { updateDescription(); } }; fHorizontalOrientation= new Action(Messages.THViewPart_HorizontalOrientation, IAction.AS_RADIO_BUTTON) { + @Override public void run() { setOrientation(ORIENTATION_HORIZONTAL); } @@ -550,6 +559,7 @@ public class THViewPart extends ViewPart implements ITHModelPresenter { CPluginImages.setImageDescriptors(fHorizontalOrientation, CPluginImages.T_LCL, CPluginImages.IMG_LCL_HORIZONTAL_ORIENTATION); fVerticalOrientation= new Action(Messages.THViewPart_VerticalOrientation, IAction.AS_RADIO_BUTTON) { + @Override public void run() { setOrientation(ORIENTATION_VERTICAL); } @@ -557,6 +567,7 @@ public class THViewPart extends ViewPart implements ITHModelPresenter { CPluginImages.setImageDescriptors(fVerticalOrientation, CPluginImages.T_LCL, CPluginImages.IMG_LCL_VERTICAL_ORIENTATION); fAutomaticOrientation= new Action(Messages.THViewPart_AutomaticOrientation, IAction.AS_RADIO_BUTTON) { + @Override public void run() { setOrientation(ORIENTATION_AUTOMATIC); } @@ -564,6 +575,7 @@ public class THViewPart extends ViewPart implements ITHModelPresenter { CPluginImages.setImageDescriptors(fAutomaticOrientation, CPluginImages.T_LCL, CPluginImages.IMG_LCL_AUTOMATIC_ORIENTATION); fSingleOrientation= new Action(Messages.THViewPart_SinglePaneOrientation, IAction.AS_RADIO_BUTTON) { + @Override public void run() { setOrientation(ORIENTATION_SINGLE); } @@ -571,6 +583,7 @@ public class THViewPart extends ViewPart implements ITHModelPresenter { CPluginImages.setImageDescriptors(fSingleOrientation, CPluginImages.T_LCL, CPluginImages.IMG_LCL_SINGLE_ORIENTATION); fShowTypeHierarchyAction= new Action(Messages.THViewPart_CompleteTypeHierarchy, IAction.AS_RADIO_BUTTON) { + @Override public void run() { if (isChecked()) { onSetHierarchyKind(THHierarchyModel.TYPE_HIERARCHY); @@ -581,6 +594,7 @@ public class THViewPart extends ViewPart implements ITHModelPresenter { CPluginImages.setImageDescriptors(fShowTypeHierarchyAction, CPluginImages.T_LCL, CPluginImages.IMG_LCL_TYPE_HIERARCHY); fShowSubTypeHierarchyAction= new Action(Messages.THViewPart_SubtypeHierarchy, IAction.AS_RADIO_BUTTON) { + @Override public void run() { if (isChecked()) { onSetHierarchyKind(THHierarchyModel.SUB_TYPE_HIERARCHY); @@ -591,6 +605,7 @@ public class THViewPart extends ViewPart implements ITHModelPresenter { CPluginImages.setImageDescriptors(fShowSubTypeHierarchyAction, CPluginImages.T_LCL, CPluginImages.IMG_LCL_SUB_TYPE_HIERARCHY); fShowSuperTypeHierarchyAction= new Action(Messages.THViewPart_SupertypeHierarchy, IAction.AS_RADIO_BUTTON) { + @Override public void run() { if (isChecked()) { onSetHierarchyKind(THHierarchyModel.SUPER_TYPE_HIERARCHY); @@ -601,6 +616,7 @@ public class THViewPart extends ViewPart implements ITHModelPresenter { CPluginImages.setImageDescriptors(fShowSuperTypeHierarchyAction, CPluginImages.T_LCL, CPluginImages.IMG_LCL_SUPER_TYPE_HIERARCHY); fShowInheritedMembersAction= new Action(Messages.THViewPart_ShowInherited_label, IAction.AS_CHECK_BOX) { + @Override public void run() { onShowInheritedMembers(isChecked()); } @@ -609,7 +625,8 @@ public class THViewPart extends ViewPart implements ITHModelPresenter { CPluginImages.setImageDescriptors(fShowInheritedMembersAction, CPluginImages.T_LCL, CPluginImages.IMG_LCL_SHOW_INHERITED_MEMBERS); fFieldFilter= new ViewerFilter() { - public boolean select(Viewer viewer, Object parentElement, Object element) { + @Override + public boolean select(Viewer viewer, Object parentElement, Object element) { if (element instanceof ICElement) { ICElement node= (ICElement) element; switch (node.getElementType()) { @@ -626,7 +643,8 @@ public class THViewPart extends ViewPart implements ITHModelPresenter { } }; fStaticFilter= new ViewerFilter() { - public boolean select(Viewer viewer, Object parentElement, Object element) { + @Override + public boolean select(Viewer viewer, Object parentElement, Object element) { if (element instanceof IDeclaration) { IDeclaration node= (IDeclaration) element; try { @@ -639,7 +657,8 @@ public class THViewPart extends ViewPart implements ITHModelPresenter { } }; fNonPublicFilter= new ViewerFilter() { - public boolean select(Viewer viewer, Object parentElement, Object element) { + @Override + public boolean select(Viewer viewer, Object parentElement, Object element) { if (element instanceof IMember) { IMember node= (IMember) element; try { @@ -652,7 +671,8 @@ public class THViewPart extends ViewPart implements ITHModelPresenter { } }; fFieldFilterAction= new Action(Messages.THViewPart_HideFields_label, IAction.AS_CHECK_BOX) { - public void run() { + @Override + public void run() { if (isChecked()) { fMemberViewer.addFilter(fFieldFilter); } @@ -665,7 +685,8 @@ public class THViewPart extends ViewPart implements ITHModelPresenter { CPluginImages.setImageDescriptors(fFieldFilterAction, CPluginImages.T_LCL, CPluginImages.IMG_ACTION_HIDE_FIELDS); fStaticFilterAction= new Action(Messages.THViewPart_HideStatic_label, IAction.AS_CHECK_BOX) { - public void run() { + @Override + public void run() { if (isChecked()) { fMemberViewer.addFilter(fStaticFilter); } @@ -678,7 +699,8 @@ public class THViewPart extends ViewPart implements ITHModelPresenter { CPluginImages.setImageDescriptors(fStaticFilterAction, CPluginImages.T_LCL, CPluginImages.IMG_ACTION_HIDE_STATIC); fNonPublicFilterAction= new Action(Messages.THViewPart_HideNonPublic_label, IAction.AS_CHECK_BOX) { - public void run() { + @Override + public void run() { if (isChecked()) { fMemberViewer.addFilter(fNonPublicFilter); } @@ -691,21 +713,24 @@ public class THViewPart extends ViewPart implements ITHModelPresenter { CPluginImages.setImageDescriptors(fNonPublicFilterAction, CPluginImages.T_LCL, CPluginImages.IMG_ACTION_SHOW_PUBLIC); fOpenElement= new Action(Messages.THViewPart_Open) { - public void run() { + @Override + public void run() { onOpenElement(getSite().getSelectionProvider().getSelection()); } }; fOpenElement.setToolTipText(Messages.THViewPart_Open_tooltip); fShowFilesInLabelsAction= new Action(Messages.THViewPart_ShowFileNames, IAction.AS_CHECK_BOX) { - public void run() { + @Override + public void run() { onShowFilesInLabels(isChecked()); } }; fShowFilesInLabelsAction.setToolTipText(Messages.THViewPart_ShowFileNames_tooltip); fRefreshAction = new Action(Messages.THViewPart_Refresh) { - public void run() { + @Override + public void run() { onRefresh(); } }; @@ -713,7 +738,8 @@ public class THViewPart extends ViewPart implements ITHModelPresenter { CPluginImages.setImageDescriptors(fRefreshAction, CPluginImages.T_LCL, CPluginImages.IMG_REFRESH); fCancelAction = new Action(Messages.THViewPart_Cancel) { - public void run() { + @Override + public void run() { onCancel(); } }; @@ -961,7 +987,7 @@ public class THViewPart extends ViewPart implements ITHModelPresenter { } public ICElement[] getHistoryEntries() { - return (ICElement[]) fHistoryEntries.toArray(new ICElement[fHistoryEntries.size()]); + return fHistoryEntries.toArray(new ICElement[fHistoryEntries.size()]); } public void setHistoryEntries(ICElement[] remaining) { diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/typehierarchy/messages.properties b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/typehierarchy/messages.properties index 10a01ecd30d..2d810d5584c 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/typehierarchy/messages.properties +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/typehierarchy/messages.properties @@ -1,5 +1,5 @@ ############################################################################### -# Copyright (c) 2007 Wind River Systems, Inc. and others. +# Copyright (c) 2007, 2008 Wind River Systems, Inc. and others. # All rights reserved. This program and the accompanying materials # are made available under the terms of the Eclipse Public License v1.0 # which accompanies this distribution, and is available at @@ -34,7 +34,6 @@ THViewPart_SubtypeHierarchy_tooltip=Show the Subtype Hierarchy THViewPart_SupertypeHierarchy=Supertype Hierarchy THViewPart_HideFields_tooltip=Hide Fields THViewPart_HideStatic_tooltip=Hide Static Fields and Methods -THGraph_error_elementNotFound=Cannot find element ''{0}'' in index. THViewPart_Open=Open THViewPart_Open_tooltip=Open THViewPart_ShowFileNames=Show File Names @@ -49,7 +48,6 @@ THViewPart_FocusOn=Focus On ''{0}'' THViewPart_Cancel=Cancel TypeHierarchyUI_OpenTypeHierarchy=Open Type Hierarchy TypeHierarchyUI_OpenFailure_message=Cannot resolve selected text to a defined type -TypeHierarchyUI_SelectFromList=Select one element from the list OpenTypeHierarchyAction_label=Open Type Hierarchy OpenTypeHierarchyAction_tooltip=Open Type Hierarchy OpenTypeInHierarchyAction_errorTitle=Open Type in Hierarchy diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/wizards/folderwizard/NewFolderWizardMessages.properties b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/wizards/folderwizard/NewFolderWizardMessages.properties index 36f2fe80a7b..be5dc176fbe 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/wizards/folderwizard/NewFolderWizardMessages.properties +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/wizards/folderwizard/NewFolderWizardMessages.properties @@ -1,5 +1,5 @@ ############################################################################### -# Copyright (c) 2004, 2006 QNX Software Systems and others. +# Copyright (c) 2004, 2007 QNX Software Systems and others. # All rights reserved. This program and the accompanying materials # are made available under the terms of the Eclipse Public License v1.0 # which accompanies this distribution, and is available at @@ -9,9 +9,6 @@ # QNX Software Systems - Initial API and implementation ############################################################################### -# ------- NewSourceFolderCreationWizard ------- -NewSourceFolderCreationWizard.title= New Source Folder - # ------- NewSourceFolderWizardPage------- NewSourceFolderCreationWizard.title=New Source Folder diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/CUIPlugin.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/CUIPlugin.java index 142c80105bd..59cac78fdb9 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/CUIPlugin.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/CUIPlugin.java @@ -68,6 +68,7 @@ import org.eclipse.cdt.core.model.ICElement; import org.eclipse.cdt.core.model.IWorkingCopy; import org.eclipse.cdt.core.model.IWorkingCopyProvider; +import org.eclipse.cdt.internal.core.dom.rewrite.ASTRewriteAnalyzer; import org.eclipse.cdt.internal.core.model.IBufferFactory; import org.eclipse.cdt.internal.corext.template.c.CContextType; import org.eclipse.cdt.internal.corext.template.c.CodeTemplateContextType; @@ -85,6 +86,7 @@ import org.eclipse.cdt.internal.ui.editor.CustomBufferFactory; import org.eclipse.cdt.internal.ui.editor.SharedTextColors; import org.eclipse.cdt.internal.ui.editor.WorkingCopyManager; import org.eclipse.cdt.internal.ui.editor.asm.AsmTextTools; +import org.eclipse.cdt.internal.ui.refactoring.CTextFileChangeFactory; import org.eclipse.cdt.internal.ui.text.CTextTools; import org.eclipse.cdt.internal.ui.text.PreferencesAdapter; import org.eclipse.cdt.internal.ui.text.c.hover.CEditorTextHoverDescriptor; @@ -461,6 +463,7 @@ public class CUIPlugin extends AbstractUIPlugin { /* * @see org.osgi.framework.BundleActivator#start(org.osgi.framework.BundleContext) */ + @Override public void start(BundleContext context) throws Exception { super.start(context); @@ -480,9 +483,11 @@ public class CUIPlugin extends AbstractUIPlugin { CDTContextActivator.getInstance().install(); DocCommentOwnerManager.getInstance().addListener(new EditorReopener()); + ASTRewriteAnalyzer.setCTextFileChangeFactory(new CTextFileChangeFactory()); // start make-ui plugin, such that it can check for project conversions. Job job= new Job(Messages.CUIPlugin_jobStartMakeUI) { + @Override protected IStatus run(IProgressMonitor monitor) { Bundle bundle= Platform.getBundle("org.eclipse.cdt.make.ui"); //$NON-NLS-1$ try { @@ -507,6 +512,7 @@ public class CUIPlugin extends AbstractUIPlugin { /* (non-Javadoc) * @see org.osgi.framework.BundleActivator#stop(org.osgi.framework.BundleContext) */ + @Override public void stop(BundleContext context) throws Exception { CDTContextActivator.getInstance().uninstall(); if (fASTProvider != null) { @@ -711,6 +717,7 @@ public class CUIPlugin extends AbstractUIPlugin { /** * {@inheritDoc} */ + @Override public IConfigurationElement getConfigurationElement(Object object) { return ((CEditorTextHoverDescriptor)object).getConfigurationElement(); } diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/refactoring/CTextFileChange.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/refactoring/CTextFileChange.java new file mode 100644 index 00000000000..e877878c23e --- /dev/null +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/refactoring/CTextFileChange.java @@ -0,0 +1,102 @@ +/******************************************************************************* + * Copyright (c) 2006, 2007 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Markus Schorn (Wind River Systems) - Initial API and implementation + * Anton Leherbauer (Wind River Systems) + *******************************************************************************/ +package org.eclipse.cdt.ui.refactoring; + +import org.eclipse.core.resources.IFile; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.jface.text.IDocument; +import org.eclipse.ltk.core.refactoring.Change; +import org.eclipse.ltk.core.refactoring.ContentStamp; +import org.eclipse.ltk.core.refactoring.TextFileChange; +import org.eclipse.text.edits.UndoEdit; + +import org.eclipse.cdt.core.model.CoreModel; +import org.eclipse.cdt.core.model.ICElement; +import org.eclipse.cdt.core.model.ITranslationUnit; +import org.eclipse.cdt.core.model.IWorkingCopy; + +import org.eclipse.cdt.internal.ui.refactoring.DocumentAdapter; +import org.eclipse.cdt.internal.ui.refactoring.UndoCTextFileChange; + + +/** + * A TextFileChange that uses a working copy in order to generate CModel events. + */ +public class CTextFileChange extends TextFileChange { + private ITranslationUnit fTranslationUnit = null; + private IWorkingCopy fWorkingCopy; + private int fAquireCount= 0; + + public CTextFileChange(String name, IFile file) { + super(name, file); + ICElement element = CoreModel.getDefault().create(file); + if(element instanceof ITranslationUnit) { + fTranslationUnit = (ITranslationUnit)element; + // "c2" is the extension which the CContentViewerCreator is registered + // with the extension point "org.eclipse.compare.contentMergeViewers" + setTextType("c2"); //$NON-NLS-1$ + } + } + + /* + * (non-Javadoc) + * @see org.eclipse.ltk.core.refactoring.TextFileChange#acquireDocument(org.eclipse.core.runtime.IProgressMonitor) + */ + @Override + protected IDocument acquireDocument(IProgressMonitor pm) throws CoreException { + IDocument doc= super.acquireDocument(pm); + if (++fAquireCount == 1) { + if (fTranslationUnit != null && fWorkingCopy == null) { + fWorkingCopy= fTranslationUnit.getWorkingCopy(null, DocumentAdapter.FACTORY); + if (!fTranslationUnit.isOpen()) { + fTranslationUnit.open(null); + } + } + } + return doc; + } + + @Override + protected void commit(final IDocument document, final IProgressMonitor pm) throws CoreException { + if (fWorkingCopy == null) { + super.commit(document, pm); + } + else if (needsSaving()) { + fWorkingCopy.commit(false, pm); + } + } + + /* + * (non-Javadoc) + * @see org.eclipse.ltk.core.refactoring.TextFileChange#releaseDocument(org.eclipse.jface.text.IDocument, org.eclipse.core.runtime.IProgressMonitor) + */ + @Override + protected void releaseDocument(IDocument document, IProgressMonitor pm) throws CoreException { + super.releaseDocument(document, pm); + if (--fAquireCount == 0) { + if (fWorkingCopy != null) { + fWorkingCopy.destroy(); + fWorkingCopy= null; + } + } + } + + /* + * (non-Javadoc) + * @see org.eclipse.ltk.core.refactoring.TextFileChange#createUndoChange(org.eclipse.text.edits.UndoEdit, org.eclipse.ltk.core.refactoring.ContentStamp) + */ + @Override + protected Change createUndoChange(UndoEdit edit, ContentStamp stampToRestore) { + return new UndoCTextFileChange(getName(), getFile(), edit, stampToRestore, getSaveMode()); + } +} diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/refactoring/actions/CRefactoringActionGroup.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/refactoring/actions/CRefactoringActionGroup.java new file mode 100644 index 00000000000..da24db11f83 --- /dev/null +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/refactoring/actions/CRefactoringActionGroup.java @@ -0,0 +1,266 @@ +/******************************************************************************* + * Copyright (c) 2004, 2008 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Rational Software - Initial API and implementation + * Markus Schorn, Wind River Systems Inc. - ported for rename refactoring impl. + *******************************************************************************/ +package org.eclipse.cdt.ui.refactoring.actions; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.jface.action.IMenuManager; +import org.eclipse.jface.action.MenuManager; +import org.eclipse.jface.action.Separator; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.ISelectionChangedListener; +import org.eclipse.jface.viewers.ISelectionProvider; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.SelectionChangedEvent; +import org.eclipse.ui.IActionBars; +import org.eclipse.ui.IWorkbenchActionConstants; +import org.eclipse.ui.IWorkbenchPart; +import org.eclipse.ui.IWorkbenchSite; +import org.eclipse.ui.actions.ActionGroup; +import org.eclipse.ui.part.Page; +import org.eclipse.ui.texteditor.ITextEditor; + +import org.eclipse.cdt.core.model.ICElement; +import org.eclipse.cdt.core.model.ISourceReference; +import org.eclipse.cdt.ui.actions.CdtActionConstants; + +import org.eclipse.cdt.internal.ui.editor.ICEditorActionDefinitionIds; + +/** + * Action group that adds refactoring actions (for example Rename..., Move..., etc) + * to a context menu and the global menu bar. + * + *

+ * This class may be instantiated; it is not intended to be subclassed. + *

+ * + * @since 2.0 + */ +public class CRefactoringActionGroup extends ActionGroup implements ISelectionChangedListener { + /** + * Pop-up menu: id of the refactor sub menu (value org.eclipse.cdt.ui.refactoring.menu). + * + * @since 2.1 + */ + public static final String MENU_ID = "org.eclipse.cdt.ui.refactoring.menu"; //$NON-NLS-1$ + + /** + * Pop-up menu: id of the reorg group of the refactor sub menu (value + * reorgGroup). + * + * @since 2.1 + */ + public static final String GROUP_REORG = "reorgGroup"; //$NON-NLS-1$ + + /** + * Pop-up menu: id of the type group of the refactor sub menu (value + * typeGroup). + * + * @since 2.1 + */ + public static final String GROUP_TYPE = "typeGroup"; //$NON-NLS-1$ + + /** + * Pop-up menu: id of the coding group of the refactor sub menu (value + * codingGroup). + * + * @since 2.1 + */ + public static final String GROUP_CODING = "codingGroup"; //$NON-NLS-1$ + + /** + * Pop-up menu: id of the coding group 2 of the refactor sub menu (value + * codingGroup2). + * + * @since 5.0 + */ + public static final String GROUP_CODING2= "codingGroup2"; //$NON-NLS-1$ + + /** + * Pop-up menu: id of the reorg group 2 of the refactor sub menu (value + * reorgGroup2). + * + * @since 5.0 + */ + public static final String GROUP_REORG2= "reorgGroup2"; //$NON-NLS-1$ + + /** + * Pop-up menu: id of the type group 2 of the refactor sub menu (value + * typeGroup2). + * + * @since 5.0 + */ + public static final String GROUP_TYPE2= "typeGroup2"; //$NON-NLS-1$ + + /** + * Pop-up menu: id of the type group 2 of the refactor sub menu (value + * typeGroup3). + * + * @since 5.0 + */ + public static final String GROUP_TYPE3= "typeGroup3"; //$NON-NLS-1$ + + private String fGroupName= IWorkbenchActionConstants.GROUP_REORGANIZE; + private CRenameAction fRenameAction; + private RefactoringAction fExtractConstantAction; + private IWorkbenchSite fSite; + private List fAllActions= new ArrayList(); + + public CRefactoringActionGroup(IWorkbenchPart part) { + this(part, null); + } + + public CRefactoringActionGroup(Page page) { + createActions(false); + setWorkbenchSite(page.getSite()); + } + + public CRefactoringActionGroup(IWorkbenchPart part, String groupName) { + if (groupName != null && groupName.length() > 0) { + fGroupName= groupName; + } + createActions(part instanceof ITextEditor); + + if (part instanceof ITextEditor) { + setEditor((ITextEditor) part); + } + else { + setWorkbenchSite(part.getSite()); + } + } + + private void createActions(boolean forEditor) { + fRenameAction = new CRenameAction(); + fRenameAction.setActionDefinitionId(ICEditorActionDefinitionIds.RENAME_ELEMENT); + fAllActions.add(fRenameAction); + + if (forEditor) { + fExtractConstantAction= new ExtractConstantAction(); + fExtractConstantAction.setActionDefinitionId(ICEditorActionDefinitionIds.EXTRACT_CONSTANT); + fAllActions.add(fExtractConstantAction); + } + } + + public void setWorkbenchSite(IWorkbenchSite site) { + unregisterSite(); + fSite= site; + + for (RefactoringAction action : fAllActions) { + action.setSite(site); + } + final ISelectionProvider sp = fSite.getSelectionProvider(); + sp.addSelectionChangedListener(this); + updateActions(sp.getSelection()); + } + + private void unregisterSite() { + if (fSite != null) { + fSite.getSelectionProvider().removeSelectionChangedListener(this); + fSite= null; + } + } + + public void setEditor(ITextEditor textEditor) { + unregisterSite(); + + for (RefactoringAction action : fAllActions) { + action.setEditor(textEditor); + } + } + + + @Override + public void fillActionBars(IActionBars actionBar) { + super.fillActionBars(actionBar); + setActionHandler(actionBar, CdtActionConstants.RENAME, fRenameAction); + setActionHandler(actionBar, CdtActionConstants.EXTRACT_CONSTANT, fExtractConstantAction); + } + + private void setActionHandler(IActionBars actionBar, String id, RefactoringAction action) { + if (action != null) + actionBar.setGlobalActionHandler(id, action); + } + + /* (non-Javadoc) + * Method declared in ActionGroup + */ + @Override + public void fillContextMenu(IMenuManager menu) { + updateActionBars(); + + boolean needMenu= false; + for (RefactoringAction action : fAllActions) { + if (action.isEnabled()) { + needMenu= true; + break; + } + } + + if (needMenu) { + IMenuManager refactorSubmenu = new MenuManager(Messages.CRefactoringActionGroup_menu, MENU_ID); + refactorSubmenu.add(new Separator(GROUP_REORG)); + addAction(refactorSubmenu, fRenameAction); + refactorSubmenu.add(new Separator(GROUP_CODING)); + addAction(refactorSubmenu, fExtractConstantAction); + refactorSubmenu.add(new Separator(GROUP_REORG2)); + refactorSubmenu.add(new Separator(GROUP_TYPE)); + refactorSubmenu.add(new Separator(GROUP_TYPE2)); + refactorSubmenu.add(new Separator(GROUP_CODING2)); + refactorSubmenu.add(new Separator(GROUP_TYPE3)); + + menu.appendToGroup(fGroupName, refactorSubmenu); + } + } + + private void addAction(IMenuManager refactorSubmenu, RefactoringAction action) { + if (action != null && action.isEnabled()) { + refactorSubmenu.add(action); + } + } + + private ICElement getCElement(ISelection selection) { + if (selection instanceof IStructuredSelection) { + IStructuredSelection ss= (IStructuredSelection) selection; + if (ss.size() == 1) { + Object o= ss.getFirstElement(); + if (o instanceof ICElement && o instanceof ISourceReference) { + return (ICElement) o; + } + } + } + return null; + } + + private void updateActions(ISelection selection) { + ICElement celem= getCElement(selection); + for (RefactoringAction action : fAllActions) { + action.updateSelection(celem); + } + } + + /* (non-Javadoc) + * @see org.eclipse.ui.actions.ActionGroup#dispose() + */ + @Override + public void dispose() { + unregisterSite(); + fSite= null; + } + + /* (non-Javadoc) + * @see org.eclipse.jface.viewers.ISelectionChangedListener#selectionChanged(org.eclipse.jface.viewers.SelectionChangedEvent) + */ + public void selectionChanged(SelectionChangedEvent event) { + updateActions(event.getSelection()); + } +} diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/refactoring/actions/CRenameAction.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/refactoring/actions/CRenameAction.java new file mode 100644 index 00000000000..cc4f9ccc7a8 --- /dev/null +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/refactoring/actions/CRenameAction.java @@ -0,0 +1,53 @@ +/******************************************************************************* + * Copyright (c) 2005, 2006 Wind River Systems, Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Markus Schorn - initial API and implementation + *******************************************************************************/ + +package org.eclipse.cdt.ui.refactoring.actions; + +import org.eclipse.jface.text.ITextSelection; +import org.eclipse.jface.window.IShellProvider; + +import org.eclipse.cdt.core.model.ICElement; +import org.eclipse.cdt.core.model.IInclude; +import org.eclipse.cdt.core.model.ITranslationUnit; +import org.eclipse.cdt.core.model.IWorkingCopy; + +import org.eclipse.cdt.internal.ui.refactoring.rename.CRefactory; + +/** + * Launches a rename refactoring. + */ +public class CRenameAction extends RefactoringAction { + + public CRenameAction() { + super(Messages.CRenameAction_label); + } + + @Override + public void run(IShellProvider shellProvider, ICElement elem) { + CRefactory.getInstance().rename(shellProvider.getShell(), elem); + } + + @Override + public void run(IShellProvider shellProvider, IWorkingCopy wc, ITextSelection s) { + CRefactory.getInstance().rename(shellProvider.getShell(), wc, s); + } + + @Override + public void updateSelection(ICElement elem) { + super.updateSelection(elem); + if (elem == null || elem instanceof IInclude || elem instanceof ITranslationUnit) { + setEnabled(false); + } + else { + setEnabled(true); + } + } +} diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/refactoring/actions/ExtractConstantAction.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/refactoring/actions/ExtractConstantAction.java new file mode 100644 index 00000000000..2e6c0dfc77b --- /dev/null +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/refactoring/actions/ExtractConstantAction.java @@ -0,0 +1,52 @@ +/******************************************************************************* + * Copyright (c) 2005, 2006 Wind River Systems, Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Markus Schorn - initial API and implementation + *******************************************************************************/ + +package org.eclipse.cdt.ui.refactoring.actions; + +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IResource; +import org.eclipse.jface.text.ITextSelection; +import org.eclipse.jface.window.IShellProvider; + +import org.eclipse.cdt.core.model.ICElement; +import org.eclipse.cdt.core.model.IWorkingCopy; + +import org.eclipse.cdt.internal.ui.refactoring.extractconstant.ExtractConstantRefactoringRunner; + +/** + * Launches a rename refactoring. + */ +public class ExtractConstantAction extends RefactoringAction { + + public ExtractConstantAction() { + super(Messages.ExtractConstantAction_label); + } + + @Override + public void run(IShellProvider shellProvider, ICElement elem) { + } + + @Override + public void run(IShellProvider shellProvider, IWorkingCopy wc, ITextSelection s) { + IResource res= wc.getResource(); + if (res instanceof IFile) { + new ExtractConstantRefactoringRunner((IFile) res, + fEditor.getSelectionProvider().getSelection(), + fEditor.getSite().getWorkbenchWindow()).run(); + } + } + + @Override + public void updateSelection(ICElement elem) { + super.updateSelection(elem); + setEnabled(false); + } +} diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/refactoring/actions/Messages.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/refactoring/actions/Messages.java new file mode 100644 index 00000000000..95be61cea71 --- /dev/null +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/refactoring/actions/Messages.java @@ -0,0 +1,27 @@ +/******************************************************************************* + * Copyright (c) 2008 Wind River Systems, Inc. and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Markus Schorn - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.ui.refactoring.actions; + +import org.eclipse.osgi.util.NLS; + +public class Messages extends NLS { + private static final String BUNDLE_NAME = "org.eclipse.cdt.ui.refactoring.actions.messages"; //$NON-NLS-1$ + public static String CRefactoringActionGroup_menu; + public static String CRenameAction_label; + public static String ExtractConstantAction_label; + static { + // initialize resource bundle + NLS.initializeMessages(BUNDLE_NAME, Messages.class); + } + + private Messages() { + } +} diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/refactoring/actions/RefactoringAction.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/refactoring/actions/RefactoringAction.java new file mode 100644 index 00000000000..978fefdcfc1 --- /dev/null +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/refactoring/actions/RefactoringAction.java @@ -0,0 +1,79 @@ +/******************************************************************************* + * Copyright (c) 2008 Wind River Systems, Inc. and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Markus Schorn - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.ui.refactoring.actions; + +import org.eclipse.jface.action.Action; +import org.eclipse.jface.text.ITextSelection; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.ISelectionProvider; +import org.eclipse.jface.window.IShellProvider; +import org.eclipse.ui.IEditorPart; +import org.eclipse.ui.IWorkbenchSite; +import org.eclipse.ui.texteditor.ITextEditor; + +import org.eclipse.cdt.core.model.ICElement; +import org.eclipse.cdt.core.model.IWorkingCopy; +import org.eclipse.cdt.ui.CUIPlugin; + +/** + * Common base class for refactoring actions + * @since 5.0 + */ +public abstract class RefactoringAction extends Action { + protected ITextEditor fEditor; + private IWorkbenchSite fSite; + private ICElement fElement; + + public RefactoringAction(String label) { + super(label); + } + + public void setEditor(IEditorPart editor) { + fEditor= null; + fSite= null; + if (editor instanceof ITextEditor) { + fEditor= (ITextEditor) editor; + } + setEnabled(fEditor!=null); + } + + public void setSite(IWorkbenchSite site) { + fEditor= null; + fSite= site; + } + + @Override + public final void run() { + if (fEditor != null) { + ISelectionProvider provider= fEditor.getSelectionProvider(); + if (provider != null) { + ISelection s= provider.getSelection(); + if (s instanceof ITextSelection) { + IWorkingCopy wc= CUIPlugin.getDefault().getWorkingCopyManager().getWorkingCopy(fEditor.getEditorInput()); + if (wc != null) + run(fEditor.getSite(), wc, (ITextSelection) s); + } + } + } + else if (fSite != null) { + if (fElement != null) { + run(fSite, fElement); + } + } + } + + public void updateSelection(ICElement elem) { + fElement= elem; + } + + public abstract void run(IShellProvider shellProvider, IWorkingCopy wc, ITextSelection s); + public abstract void run(IShellProvider shellProvider, ICElement elem); +} diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/refactoring/actions/messages.properties b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/refactoring/actions/messages.properties new file mode 100644 index 00000000000..65445cd7ca7 --- /dev/null +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/refactoring/actions/messages.properties @@ -0,0 +1,13 @@ +############################################################################### +# Copyright (c) 2008 Wind River Systems, Inc. and others. +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Eclipse Public License v1.0 +# which accompanies this distribution, and is available at +# http://www.eclipse.org/legal/epl-v10.html +# +# Contributors: +# Markus Schorn (Wind River Systems) +############################################################################### +CRefactoringActionGroup_menu=Refactor +CRenameAction_label=Rename... +ExtractConstantAction_label=Extract Constant... diff --git a/releng/org.eclipse.cdt-feature/feature.xml b/releng/org.eclipse.cdt-feature/feature.xml index 78850b873c3..e093f54e0a2 100644 --- a/releng/org.eclipse.cdt-feature/feature.xml +++ b/releng/org.eclipse.cdt-feature/feature.xml @@ -232,13 +232,6 @@ version="0.0.0" unpack="false"/> - - - - - - - - diff --git a/releng/org.eclipse.cdt.releng/maps/cdt.map b/releng/org.eclipse.cdt.releng/maps/cdt.map index 84f70a0ea8a..b542c96aabf 100644 --- a/releng/org.eclipse.cdt.releng/maps/cdt.map +++ b/releng/org.eclipse.cdt.releng/maps/cdt.map @@ -4,7 +4,6 @@ feature@org.eclipse.cdt.master=@cdtTag@,:pserver:anonymous@dev.eclipse.org:/cvsr ! Cross platform plugin@org.eclipse.cdt.core=@cdtTag@,:pserver:anonymous@dev.eclipse.org:/cvsroot/tools,,org.eclipse.cdt/all/org.eclipse.cdt.core plugin@org.eclipse.cdt.ui=@cdtTag@,:pserver:anonymous@dev.eclipse.org:/cvsroot/tools,,org.eclipse.cdt/all/org.eclipse.cdt.ui -plugin@org.eclipse.cdt.refactoring=@cdtTag@,:pserver:anonymous@dev.eclipse.org:/cvsroot/tools,,org.eclipse.cdt/all/org.eclipse.cdt.refactoring plugin@org.eclipse.cdt.make.core=@cdtTag@,:pserver:anonymous@dev.eclipse.org:/cvsroot/tools,,org.eclipse.cdt/all/org.eclipse.cdt.make.core plugin@org.eclipse.cdt.make.ui=@cdtTag@,:pserver:anonymous@dev.eclipse.org:/cvsroot/tools,,org.eclipse.cdt/all/org.eclipse.cdt.make.ui @@ -42,7 +41,6 @@ fragment@org.eclipse.cdt.core.win32=@cdtTag@,:pserver:anonymous@dev.eclipse.org: ! Testing feature plugin@org.eclipse.cdt.core.tests=@cdtTag@,:pserver:anonymous@dev.eclipse.org:/cvsroot/tools,,org.eclipse.cdt/all/org.eclipse.cdt.core.tests plugin@org.eclipse.cdt.ui.tests=@cdtTag@,:pserver:anonymous@dev.eclipse.org:/cvsroot/tools,,org.eclipse.cdt/all/org.eclipse.cdt.ui.tests -plugin@org.eclipse.cdt.refactoring.tests=@cdtTag@,:pserver:anonymous@dev.eclipse.org:/cvsroot/tools,,org.eclipse.cdt/all/org.eclipse.cdt.refactoring.tests plugin@org.eclipse.cdt.debug.ui.tests=@cdtTag@,:pserver:anonymous@dev.eclipse.org:/cvsroot/tools,,org.eclipse.cdt/all/org.eclipse.cdt.debug.ui.tests plugin@org.eclipse.cdt.managedbuilder.core.tests=@cdtTag@,:pserver:anonymous@dev.eclipse.org:/cvsroot/tools,,org.eclipse.cdt/all/org.eclipse.cdt.managedbuilder.core.tests plugin@org.eclipse.cdt.managedbuilder.ui.tests=@cdtTag@,:pserver:anonymous@dev.eclipse.org:/cvsroot/tools,,org.eclipse.cdt/all/org.eclipse.cdt.managedbuilder.ui.tests diff --git a/releng/org.eclipse.cdt.testing-feature/feature.xml b/releng/org.eclipse.cdt.testing-feature/feature.xml index 3622f3798f9..12392444bfd 100644 --- a/releng/org.eclipse.cdt.testing-feature/feature.xml +++ b/releng/org.eclipse.cdt.testing-feature/feature.xml @@ -42,7 +42,6 @@ - @@ -102,10 +101,4 @@ install-size="0" version="0.0.0"/> - -