From 628943cbcabc5bebc326076387af6a6cf5cc0d84 Mon Sep 17 00:00:00 2001 From: Markus Schorn Date: Mon, 8 Feb 2010 09:34:31 +0000 Subject: [PATCH] Bug 301780: Placement of include directives by add include --- .../addInclude/InsertionPoint_301780.cpp | 6 +++ .../InsertionPoint_301780.cpp.expected | 7 +++ .../addInclude/InsertionPoint_301780.h | 1 + .../cdt/ui/tests/text/AddIncludeTest.java | 9 +++- .../AddIncludesOperation.java | 47 +++++++++++++++++-- 5 files changed, 65 insertions(+), 5 deletions(-) create mode 100644 core/org.eclipse.cdt.ui.tests/resources/addInclude/InsertionPoint_301780.cpp create mode 100644 core/org.eclipse.cdt.ui.tests/resources/addInclude/InsertionPoint_301780.cpp.expected create mode 100644 core/org.eclipse.cdt.ui.tests/resources/addInclude/InsertionPoint_301780.h diff --git a/core/org.eclipse.cdt.ui.tests/resources/addInclude/InsertionPoint_301780.cpp b/core/org.eclipse.cdt.ui.tests/resources/addInclude/InsertionPoint_301780.cpp new file mode 100644 index 00000000000..d91602f62cb --- /dev/null +++ b/core/org.eclipse.cdt.ui.tests/resources/addInclude/InsertionPoint_301780.cpp @@ -0,0 +1,6 @@ +#ifndef TST_H_ +#define TST_H_ + +XXX var; + +#endif /* TST_H_ */ diff --git a/core/org.eclipse.cdt.ui.tests/resources/addInclude/InsertionPoint_301780.cpp.expected b/core/org.eclipse.cdt.ui.tests/resources/addInclude/InsertionPoint_301780.cpp.expected new file mode 100644 index 00000000000..d61859864ae --- /dev/null +++ b/core/org.eclipse.cdt.ui.tests/resources/addInclude/InsertionPoint_301780.cpp.expected @@ -0,0 +1,7 @@ +#ifndef TST_H_ +#define TST_H_ +#include "InsertionPoint_301780.h" + +XXX var; + +#endif /* TST_H_ */ diff --git a/core/org.eclipse.cdt.ui.tests/resources/addInclude/InsertionPoint_301780.h b/core/org.eclipse.cdt.ui.tests/resources/addInclude/InsertionPoint_301780.h new file mode 100644 index 00000000000..6215bf8bb99 --- /dev/null +++ b/core/org.eclipse.cdt.ui.tests/resources/addInclude/InsertionPoint_301780.h @@ -0,0 +1 @@ +typedef int XXX; diff --git a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/AddIncludeTest.java b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/AddIncludeTest.java index 962648d7b3a..e38450a27af 100644 --- a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/AddIncludeTest.java +++ b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/AddIncludeTest.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2009 Google, Inc and others. + * Copyright (c) 2009, 2010 Google, 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 @@ -7,6 +7,7 @@ * * Contributors: * Sergey Prigogin (Google) - initial API and implementation + * Markus Schorn (Wind River Systems) *******************************************************************************/ package org.eclipse.cdt.ui.tests.text; @@ -38,6 +39,7 @@ public class AddIncludeTest extends TestCase { private static final String PROJECT= "AddIncludeTests"; private static final class EmptyBundle extends ListResourceBundle { + @Override protected Object[][] getContents() { return new Object[0][]; } @@ -135,4 +137,9 @@ public class AddIncludeTest extends TestCase { select("ONE"); assertAddIncludeResult(); } + + public void testInsertionPoint_301780() throws Exception { + select("XXX"); + assertAddIncludeResult(); + } } diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/corext/codemanipulation/AddIncludesOperation.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/corext/codemanipulation/AddIncludesOperation.java index a9f5b5a969f..3b1f8b28796 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/corext/codemanipulation/AddIncludesOperation.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/corext/codemanipulation/AddIncludesOperation.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2009 IBM Corporation and others. + * Copyright (c) 2000, 2010 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 @@ -9,8 +9,8 @@ * IBM Corporation - initial API and implementation * QNX Software Systems * Sergey Prigogin (Google) + * Markus Schorn (Wind River Systems) *******************************************************************************/ - package org.eclipse.cdt.internal.corext.codemanipulation; import java.util.ArrayList; @@ -30,6 +30,7 @@ import org.eclipse.text.edits.InsertEdit; import org.eclipse.cdt.core.model.CModelException; import org.eclipse.cdt.core.model.IBuffer; import org.eclipse.cdt.core.model.ICElement; +import org.eclipse.cdt.core.model.IMacro; import org.eclipse.cdt.core.model.ISourceRange; import org.eclipse.cdt.core.model.ISourceReference; import org.eclipse.cdt.core.model.ITranslationUnit; @@ -52,6 +53,7 @@ public class AddIncludesOperation implements IWorkspaceRunnable { private List fExistingUsings; private InsertEdit fIncludesInsert; private InsertEdit fUsingsInsert; + private int fIncludesPos= -1; /** * @param tu a translation unit. @@ -145,10 +147,21 @@ public class AddIncludesOperation implements IWorkspaceRunnable { } } - int pos = getOffsetAfterLast(fExistingIncludes); + int pos= getIncludeInsertionPosition(); return new InsertEdit(pos, buf.toString()); } + private int getIncludeInsertionPosition() throws CModelException { + if (fIncludesPos < 0) { + if (fExistingIncludes.isEmpty()) { + fIncludesPos= getOffsetAfterLeadingMacroDefinitions(); + } else { + fIncludesPos = getOffsetAfterLast(fExistingIncludes); + } + } + return fIncludesPos; + } + private InsertEdit getUsingsInsert() throws CoreException { if (fUsings == null || fUsings.length == 0) { return null; @@ -182,7 +195,7 @@ public class AddIncludesOperation implements IWorkspaceRunnable { } int pos = getOffsetAfterLast(fExistingUsings); - int pos2 = getOffsetAfterLast(fExistingIncludes); + int pos2 = getIncludeInsertionPosition(); if (pos <= pos2) { pos = pos2; buf.insert(0, fNewLine); // Add a blank line between #include and using statements. @@ -209,6 +222,32 @@ public class AddIncludesOperation implements IWorkspaceRunnable { return 0; } + /** + * Find the last leading macro definition before fBeforeOffset. + * And returns the offset of the line after. + */ + private int getOffsetAfterLeadingMacroDefinitions() throws CModelException { + ISourceRange found= null; + for (ICElement child: fTranslationUnit.getChildren()) { + if (!(child instanceof IMacro) || !(child instanceof ISourceReference)) + break; + + final ISourceReference sourceRef = (ISourceReference) child; + if (!sourceRef.isActive()) + break; + + ISourceRange range= sourceRef.getSourceRange(); + if (range.getStartPos() + range.getLength() > fBeforeOffset) + break; + + found= range; + } + if (found != null) { + return findNewLine(found.getStartPos() + found.getLength()); + } + return 0; + } + private int findNewLine(int pos) { while (fBuffer.getChar(pos) != '\n') { pos++;