From 1386247a0e7ac1d44e7ff2688bd9c8ae553932e9 Mon Sep 17 00:00:00 2001 From: Martin Stumpf Date: Wed, 25 Jun 2014 23:37:23 +0200 Subject: [PATCH] Bug 436041 - doxygen tags are not generated when using single line format /// or //! Change-Id: I1c392d1ea360efcc62328ce1541a42439948706b Signed-off-by: Martin Stumpf --- .../text/doctools/DocCommentTestSuite.java | 4 +- ...genCCommentSingleAutoEditStrategyTest.java | 711 ++++++++++++++++++ core/org.eclipse.cdt.ui/META-INF/MANIFEST.MF | 2 +- core/org.eclipse.cdt.ui/pom.xml | 2 +- .../DoxygenSingleAutoEditStrategy.java | 217 ++++++ .../doxygen/DoxygenSingleConfiguration.java | 5 +- 6 files changed, 935 insertions(+), 6 deletions(-) create mode 100644 core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/doctools/doxygen/DoxygenCCommentSingleAutoEditStrategyTest.java create mode 100644 core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/text/doctools/doxygen/DoxygenSingleAutoEditStrategy.java diff --git a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/doctools/DocCommentTestSuite.java b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/doctools/DocCommentTestSuite.java index 651f431cdca..d3db21fc779 100644 --- a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/doctools/DocCommentTestSuite.java +++ b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/doctools/DocCommentTestSuite.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2008 Symbian Software Systems and others. + * Copyright (c) 2008, 2015 Symbian 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 @@ -11,6 +11,7 @@ package org.eclipse.cdt.ui.tests.text.doctools; import org.eclipse.cdt.ui.tests.text.doctools.doxygen.DoxygenCCommentAutoEditStrategyTest; +import org.eclipse.cdt.ui.tests.text.doctools.doxygen.DoxygenCCommentSingleAutoEditStrategyTest; import junit.framework.TestSuite; @@ -26,5 +27,6 @@ public class DocCommentTestSuite extends TestSuite { addTest(CommentOwnerManagerTests.suite()); addTest(DocCommentHighlightingTest.suite()); addTest(DoxygenCCommentAutoEditStrategyTest.suite()); + addTest(DoxygenCCommentSingleAutoEditStrategyTest.suite()); } } diff --git a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/doctools/doxygen/DoxygenCCommentSingleAutoEditStrategyTest.java b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/doctools/doxygen/DoxygenCCommentSingleAutoEditStrategyTest.java new file mode 100644 index 00000000000..c42f3e7c596 --- /dev/null +++ b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/doctools/doxygen/DoxygenCCommentSingleAutoEditStrategyTest.java @@ -0,0 +1,711 @@ +/******************************************************************************* + * Copyright (c) 2006, 2015 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: + * Anton Leherbauer (Wind River Systems) - initial API and implementation + * Sergey Prigogin (Google) + * Andrew Ferguson (Symbian) + *******************************************************************************/ +package org.eclipse.cdt.ui.tests.text.doctools.doxygen; + +import java.util.HashMap; + +import junit.framework.Test; + +import org.eclipse.core.resources.IFile; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.jface.text.BadLocationException; +import org.eclipse.jface.text.Document; +import org.eclipse.jface.text.IDocument; + +import org.eclipse.cdt.core.CCorePlugin; +import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit; +import org.eclipse.cdt.core.model.CoreModel; +import org.eclipse.cdt.core.model.ICProject; +import org.eclipse.cdt.core.testplugin.CProjectHelper; +import org.eclipse.cdt.core.testplugin.util.TestSourceReader; +import org.eclipse.cdt.ui.CUIPlugin; +import org.eclipse.cdt.ui.tests.text.AbstractAutoEditTest; +import org.eclipse.cdt.ui.text.ICPartitions; +import org.eclipse.cdt.ui.text.doctools.DefaultMultilineCommentAutoEditStrategy; +import org.eclipse.cdt.ui.text.doctools.doxygen.DoxygenSingleAutoEditStrategy; + +import org.eclipse.cdt.internal.core.model.TranslationUnit; + +import org.eclipse.cdt.internal.ui.text.CAutoIndentStrategy; +import org.eclipse.cdt.internal.ui.text.CTextTools; + +/** + * Testing the auto indent strategies. + */ +public class DoxygenCCommentSingleAutoEditStrategyTest extends AbstractAutoEditTest { + private HashMap fOptions; + protected ICProject fCProject; + + /** + * @param name + */ + public DoxygenCCommentSingleAutoEditStrategyTest(String name) { + super(name); + } + + public static Test suite() { + return suite(DoxygenCCommentSingleAutoEditStrategyTest.class); + } + + @Override + protected void setUp() throws Exception { + super.setUp(); + fOptions= CCorePlugin.getOptions(); + fCProject= CProjectHelper.createCCProject("test" + System.currentTimeMillis(), null); + } + + /* + * @see junit.framework.TestCase#tearDown() + */ + @Override + protected void tearDown() throws Exception { + CCorePlugin.setOptions(fOptions); + CProjectHelper.delete(fCProject); + super.tearDown(); + } + + private AutoEditTester createAutoEditTester() { + CTextTools textTools = CUIPlugin.getDefault().getTextTools(); + IDocument doc = new Document(); + textTools.setupCDocument(doc); + AutoEditTester tester = new AutoEditTester(doc, ICPartitions.C_PARTITIONING); + + tester.setAutoEditStrategy(IDocument.DEFAULT_CONTENT_TYPE, new CAutoIndentStrategy(ICPartitions.C_PARTITIONING, null)); + tester.setAutoEditStrategy(ICPartitions.C_MULTI_LINE_COMMENT, new DefaultMultilineCommentAutoEditStrategy()); + tester.setAutoEditStrategy(ICPartitions.C_PREPROCESSOR, new CAutoIndentStrategy(ICPartitions.C_PARTITIONING, null)); + return tester; + } + + // ///X + // void foo() {} + + // /// + // /// X + // void foo() {} + public void testAutoDocCommentContent1() throws CoreException { + assertAutoEditBehaviour(); + } + + // /// X + // void foo() {} + + // /// + // /// X + // void foo() {} + public void testAutoDocCommentContent2() throws CoreException { + assertAutoEditBehaviour(); + } + + // /// aXb + // void foo() {} + + // /// a + // /// Xb + // void foo() {} + public void testAutoDocCommentContent2b() throws CoreException { + assertAutoEditBehaviour(); + } + + // ///X + // int foo_bar() {} + + // /// X@return + // int foo_bar() {} + public void testAutoDocCommentContent3() throws CoreException { + assertAutoEditBehaviour(); + } + + + // /// X + // int foo_bar() {} + + // /// X@return + // int foo_bar() {} + public void testAutoDocCommentContent4() throws CoreException { + assertAutoEditBehaviour(); + } + + // ///X + // /// + // /// + // int foo_bar() {} + + // /// + // /// X + // /// + // /// + // int foo_bar() {} + public void testAutoDocCommentContent5() throws CoreException { + assertAutoEditBehaviour(); + } + + // ///X + // void foo_bar(int x) {} + + // /// X@param x + // void foo_bar(int x) {} + public void testAutoDocCommentContent6() throws CoreException { + assertAutoEditBehaviour(); + } + + // /// X + // void foo_bar(int x) {} + + // /// X@param x + // void foo_bar(int x) {} + public void testAutoDocCommentContent6b() throws CoreException { + assertAutoEditBehaviour(); + } + + // class A {}; class B {}; + // ///X + // C* bar_baz(A a, B b, int c) {} + + // class A {}; class B {}; + // /// X@param a + // /// @param b + // /// @param c + // /// @return + // C* bar_baz(A a, B b, int c) {} + public void testAutoDocCommentContent7() throws CoreException { + assertAutoEditBehaviour(); + } + + // class A {}; class B {}; + // /// X@param a + // /// @param b + // /// @param c + // /// @return + // C* bar_baz(A a, B b, int c) {} + + // class A {}; class B {}; + // /// + // /// X@param a + // /// @param b + // /// @param c + // /// @return + // C* bar_baz(A a, B b, int c) {} + public void testAutoDocCommentContent7b() throws CoreException { + assertAutoEditBehaviour(); + } + + // /** + // * namespace + // */ + // namespace NS { + // class A { + // private: + // /* + // * TODO + // */ + // /*! + // * class + // */ + // class B { + // public: + // /// + // /// + // /// + // void foo() {} + // ///X + // A bar(A as[], B bs[]) {} + // }; + // }; + // } + + // /** + // * namespace + // */ + // namespace NS { + // class A { + // private: + // /* + // * TODO + // */ + // /*! + // * class + // */ + // class B { + // public: + // /// + // /// + // /// + // void foo() {} + // /// X@param as + // /// @param bs + // /// @return + // A bar(A as[], B bs[]) {} + // }; + // }; + // } + public void testAutoDocCommentContent8() throws CoreException { + assertAutoEditBehaviour(); + } + + // void foo_bar(int x) + // ///X + // {} + + // void foo_bar(int x) + // /// X@param x + // {} + public void testAutoDocCommentContent9() throws CoreException { + assertAutoEditBehaviour(); + } + + // void foo_bar(int x) + // /// X@param x + // {} + + // void foo_bar(int x) + // /// + // /// X@param x + // {} + public void testAutoDocCommentContent9b() throws CoreException { + assertAutoEditBehaviour(); + } + // void foo_bar(int x) + // /// X@param x + // {} + + // void foo_bar(int x) + // /// + // /// X@param x + // {} + public void testAutoDocCommentContent9c() throws CoreException { + assertAutoEditBehaviour(); + } + + // /// + // /// + // /// + // void foo_bar(int x) + // ///X + // {} + + // /// + // /// + // /// + // void foo_bar(int x) + // /// X@param x + // {} + public void testAutoDocCommentContent9d() throws CoreException { + assertAutoEditBehaviour(); + } + + // void foo_bar(int x) + // { + // ///X + // } + + // void foo_bar(int x) + // { + // /// + // /// X + // } + public void testAutoDocCommentContent9e() throws CoreException { + assertAutoEditBehaviour(); + } + + // void foo_bar(int x) + // { + // ///X + // } + + // void foo_bar(int x) + // { + // /// + // /// X + // /// @param x + // } + public void _testAutoDocCommentContent10() throws CoreException { + assertAutoEditBehaviour(); + // TODO - desired behaviour when there is a comment preceding the declaration + // or when there is a comment after the signature but before the brace, both need defining + } + + // ///X + // enum A { B, C }; + + // /// + // /// X + // enum A { B, C }; + public void testAutoDocCommentContent11() throws CoreException { + assertAutoEditBehaviour(); + } + + // ///X + // enum A { B, + // C }; + + // /// + // /// X + // enum A { B,//!< B + // C }; //!< C + public void testAutoDocCommentContent13() throws CoreException { + assertAutoEditBehaviour(); + } + + // ///X + // enum A { B, + // C };//!< C + + // /// + // /// X + // enum A { B,//!< B + // C };//!< C + public void testAutoDocCommentContent14() throws CoreException { + assertAutoEditBehaviour(); + } + + // ///X + // enum A { B,//!< B + // C }; + + // /// + // /// X + // enum A { B,//!< B + // C };//!< C + public void testAutoDocCommentContent15() throws CoreException { + assertAutoEditBehaviour(); + } + + // ///X + // enum A { B, + // C }; + + // /// + // /// X + // enum A { B,//!< B + // C }; //!< C + public void _testAutoDocCommentContent16() throws CoreException { + /* + * Indenting in the presence of tabs is not handled at the moment. + */ + assertAutoEditBehaviour(); + } + + // #define STATIC static + // + // class D { + // public: + // ///X + // STATIC void D::foo(int x) { + // + // } + // }; + + // #define STATIC static + // + // class D { + // public: + // /// X@param x + // STATIC void D::foo(int x) { + // + // } + // }; + public void testAutoDocCommentContent17() throws CoreException { + assertAutoEditBehaviour(); + } + + // class D { + // public: + // ///X + // virtual void foo(D x) = 0; + // }; + + // class D { + // public: + // /// X@param x + // virtual void foo(D x) = 0; + // }; + public void testAutoDocCommentContent18() throws CoreException { + assertAutoEditBehaviour(); + } + + // class D { + // public: + // ///X + // virtual void foo(D x); + // }; + + // class D { + // public: + // /// X@param x + // virtual void foo(D x); + // }; + public void testAutoDocCommentContent19() throws CoreException { + assertAutoEditBehaviour(); + } + + // class A {}; + // ///X + // A baz; + + // class A {}; + // /// + // /// X + // A baz; + public void testAutoDocCommentContent20() throws CoreException { + assertAutoEditBehaviour(); + } + + // ///X + // void foo(void) {} + + // /// + // /// X + // void foo(void) {} + public void testAutoDocCommentContent21_238852_a() throws CoreException { + assertAutoEditBehaviour(); + } + + // ///X + // void foo(void* x) {} + + // /// X@param x + // void foo(void* x) {} + public void testAutoDocCommentContent21_238852_b() throws CoreException { + assertAutoEditBehaviour(); + } + + // ///X + // void foo(void (*fp)()) {} + + // /// X@param fp + // void foo(void (*fp)()) {} + public void testAutoDocCommentContent21_238852_c() throws CoreException { + assertAutoEditBehaviour(); + } + + // ///X + // void foo(void vs[]) {} + + // /// X@param vs + // void foo(void vs[]) {} + public void testAutoDocCommentContent21_238852_d() throws CoreException { + assertAutoEditBehaviour(); + } + + /** Declarations **/ + + // ///X + // int foo_bar(); + + // /// X@return + // int foo_bar(); + public void testAutoDocCommentContent3_Dec() throws CoreException { + assertAutoEditBehaviour(); + } + + // /// X + // int foo_bar(); + + // /// X@return + // int foo_bar(); + public void testAutoDocCommentContent4_Dec() throws CoreException { + assertAutoEditBehaviour(); + } + + // /// abcX@return + // int foo_bar(); + + // /// abc + // /// X@return + // int foo_bar(); + public void testAutoDocCommentContent4b_Dec() throws CoreException { + assertAutoEditBehaviour(); + } + + // ///X + // /// + // int foo_bar(); + + // /// + // /// X + // /// + // int foo_bar(); + public void testAutoDocCommentContent5_Dec() throws CoreException { + assertAutoEditBehaviour(); + } + + // ///X + // void foo_bar(int x); + + // /// X@param x + // void foo_bar(int x); + public void testAutoDocCommentContent6_Dec() throws CoreException { + assertAutoEditBehaviour(); + } + + // class A {}; class B {}; + // ///X + // C* bar_baz(A a, B b, int c); + + // class A {}; class B {}; + // /// X@param a + // /// @param b + // /// @param c + // /// @return + // C* bar_baz(A a, B b, int c); + public void testAutoDocCommentContent7_Dec() throws CoreException { + assertAutoEditBehaviour(); + } + + // #define STATIC static + // + // class D { + // public: + // ///X + // STATIC void D::foo(int x); + // }; + + // #define STATIC static + // + // class D { + // public: + // /// X@param x + // STATIC void D::foo(int x); + // }; + public void testAutoDocCommentContent17_Dec() throws CoreException { + assertAutoEditBehaviour(); + } + + // ///X + // extern "C" void foo(int x); + + // /// X@param x + // extern "C" void foo(int x); + public void testAutoDocCommentExternC1() throws CoreException { + assertAutoEditBehaviour(); + } + + // ///X + // extern "C" { + // void foo(int x); + // } + + // /// + // /// X + // extern "C" { + // void foo(int x); + // } + public void testAutoDocCommentExternC2() throws CoreException { + assertAutoEditBehaviour(); + } + + // extern "C" { + // ///X + // void foo(int x); + // } + + // extern "C" { + // /// X@param x + // void foo(int x); + // } + public void testAutoDocCommentExternC3() throws CoreException { + assertAutoEditBehaviour(); + } + + // class Test { + // public: + // ///X + // Test(); + // }; + + // class Test { + // public: + // /// + // /// X + // Test(); + // }; + public void testAutoDocCommentConstructor1() throws CoreException { + assertAutoEditBehaviour(); + } + + // class Test { + // public: + // ///X + // Test(int x); + // }; + + // class Test { + // public: + // /// X@param x + // Test(int x); + // }; + public void testAutoDocCommentConstructor2() throws CoreException { + assertAutoEditBehaviour(); + } + + // class Test { + // public: + // ///X + // ~Test(); + // }; + + // class Test { + // public: + // /// + // /// X + // ~Test(); + // }; + public void testAutoDocCommentDestructor() throws CoreException { + assertAutoEditBehaviour(); + } + + protected void assertAutoEditBehaviour() throws CoreException { + CTextTools textTools = CUIPlugin.getDefault().getTextTools(); + final IDocument doc = new Document(); + textTools.setupCDocument(doc); + + CharSequence[] raw= getTestContents(); + String init= raw[0].toString(), expected= raw[1].toString(); + + int caretInit= init.indexOf('X'); + init= init.replaceFirst("X", ""); + + int caretExpected= expected.indexOf('X'); + expected= expected.replaceFirst("X", ""); + + + DoxygenSingleAutoEditStrategy ds= new DoxygenSingleAutoEditStrategy() { + @Override + public IASTTranslationUnit getAST() { + final IFile file= fCProject.getProject().getFile("testContent.cpp"); + try { + TestSourceReader.createFile(fCProject.getProject(), "testContent.cpp", doc.get()); + String id = CoreModel.getRegistedContentTypeId(file.getProject(), file.getName()); + return new TranslationUnit(fCProject, file, id).getAST(); + } catch(CoreException ce) { + assertTrue("Could not get test content AST", false); + return null; + } + } + }; + + + doc.set(init); + int caretActual= -1; + try { + TestDocumentCommand dc= new TestDocumentCommand(caretInit, 0, "\n"); + ds.customizeDocumentCommand(doc, dc); + caretActual= dc.exec(doc); + } catch(BadLocationException ble) { + fail(ble.getMessage()); + } + String actual= doc.get(); + assertEquals(expected, actual); + assertEquals(caretExpected, caretActual); + } +} diff --git a/core/org.eclipse.cdt.ui/META-INF/MANIFEST.MF b/core/org.eclipse.cdt.ui/META-INF/MANIFEST.MF index 013add3ee6b..9b97619ec8b 100644 --- a/core/org.eclipse.cdt.ui/META-INF/MANIFEST.MF +++ b/core/org.eclipse.cdt.ui/META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: %pluginName Bundle-SymbolicName: org.eclipse.cdt.ui; singleton:=true -Bundle-Version: 5.10.0.qualifier +Bundle-Version: 5.11.0.qualifier Bundle-Activator: org.eclipse.cdt.ui.CUIPlugin Bundle-Vendor: %providerName Bundle-Localization: plugin diff --git a/core/org.eclipse.cdt.ui/pom.xml b/core/org.eclipse.cdt.ui/pom.xml index 4d651f18315..fb7a8ba58e1 100644 --- a/core/org.eclipse.cdt.ui/pom.xml +++ b/core/org.eclipse.cdt.ui/pom.xml @@ -11,7 +11,7 @@ ../../pom.xml - 5.10.0-SNAPSHOT + 5.11.0-SNAPSHOT org.eclipse.cdt.ui eclipse-plugin diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/text/doctools/doxygen/DoxygenSingleAutoEditStrategy.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/text/doctools/doxygen/DoxygenSingleAutoEditStrategy.java new file mode 100644 index 00000000000..a643f83a4ad --- /dev/null +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/text/doctools/doxygen/DoxygenSingleAutoEditStrategy.java @@ -0,0 +1,217 @@ +/******************************************************************************* + * Copyright (c) 2008, 2015 Symbian 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 + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Andrew Ferguson (Symbian) - Initial implementation + * Martin Stumpf - adapted orginal to cope with single line comments + *******************************************************************************/ +package org.eclipse.cdt.ui.text.doctools.doxygen; + + +import org.eclipse.jface.text.BadLocationException; +import org.eclipse.jface.text.DocumentCommand; +import org.eclipse.jface.text.DocumentRewriteSession; +import org.eclipse.jface.text.DocumentRewriteSessionType; +import org.eclipse.jface.text.IAutoEditStrategy; +import org.eclipse.jface.text.IDocument; +import org.eclipse.jface.text.IDocumentExtension4; +import org.eclipse.jface.text.IRegion; +import org.eclipse.jface.text.ITypedRegion; +import org.eclipse.jface.text.Region; +import org.eclipse.jface.text.TextUtilities; + +import org.eclipse.cdt.core.dom.ast.IASTDeclaration; +import org.eclipse.cdt.core.dom.ast.IASTNode; +import org.eclipse.cdt.core.dom.ast.IASTNodeSelector; +import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit; +import org.eclipse.cdt.ui.text.ICPartitions; + +/** + * {@link IAutoEditStrategy} for adding Doxygen tags for comments. + * + * @since 5.11 + * @noextend This class is not intended to be subclassed by clients. + */ +public class DoxygenSingleAutoEditStrategy extends DoxygenMultilineAutoEditStrategy { + private static final String SLASH_COMMENT = "///"; //$NON-NLS-1$ + private static final String EXCL_COMMENT = "//!"; //$NON-NLS-1$ + private static String fgDefaultLineDelim = "\n"; //$NON-NLS-1$ + + + public DoxygenSingleAutoEditStrategy() { + } + + /** + * @see org.eclipse.jface.text.IAutoEditStrategy#customizeDocumentCommand(org.eclipse.jface.text.IDocument, org.eclipse.jface.text.DocumentCommand) + */ + @Override + public void customizeDocumentCommand(IDocument doc, DocumentCommand cmd) { + fgDefaultLineDelim = TextUtilities.getDefaultLineDelimiter(doc); + if(doc instanceof IDocumentExtension4) { + boolean forNewLine= cmd.length == 0 && cmd.text != null && endsWithDelimiter(doc, cmd.text); + + if(forNewLine ) { + IDocumentExtension4 ext4= (IDocumentExtension4) doc; + DocumentRewriteSession drs= ext4.startRewriteSession(DocumentRewriteSessionType.UNRESTRICTED_SMALL); + try { + customizeDocumentAfterNewLine(doc, cmd); + } finally { + ext4.stopRewriteSession(drs); + } + } + } + } + + @Override + public void customizeDocumentAfterNewLine(IDocument doc, final DocumentCommand c) { + int offset= c.offset; + if (offset == -1 || doc.getLength() == 0) + return; + + final StringBuilder buf= new StringBuilder(c.text); + try { + IRegion line= doc.getLineInformationOfOffset(c.offset); + String lineDelimiter = doc.getLineDelimiter(doc.getLineOfOffset(c.offset)); + int lineDelimiterLength = lineDelimiter.length(); + + + IRegion prefix= findPrefixRange(doc, line); + String indentationWithPrefix = doc.get(prefix.getOffset(), prefix.getLength()); + String commentPrefix = getCommentPrefix(indentationWithPrefix); + String commentContent = doc.get(prefix.getOffset() + prefix.getLength(), + line.getLength() - prefix.getLength()); + //String commentContentBeforeCursor = doc.get(prefix.getOffset() + prefix.getLength(), + // c.offset - line.getOffset() - prefix.getLength()); + String commentContentBehindCursor = doc.get(c.offset, + line.getLength() - (c.offset - line.getOffset())); + + buf.append(indentationWithPrefix); + + + boolean commentAtStart = prefix.getOffset() + prefix.getLength() <= c.offset; + boolean commentFollows = false; + boolean commentAhead = false; + boolean firstLineContainsText = commentContent.trim().length() > 0; + + if (commentAtStart) { + if (line.getOffset() + line.getLength() + lineDelimiterLength < doc.getLength()) + { + IRegion nextLine = doc.getLineInformationOfOffset(line.getOffset() + line.getLength() + lineDelimiterLength); + commentFollows = doc.get(nextLine.getOffset(), nextLine.getLength()).trim().startsWith(commentPrefix); + + if (line.getOffset() >= 1) + { + IRegion previousLine = doc.getLineInformationOfOffset(line.getOffset() - 1); + commentAhead = doc.get(previousLine.getOffset(), previousLine.getLength()).trim().startsWith(commentPrefix); + } + } + // comment started on this line + buf.append(" "); //$NON-NLS-1$ + } + + c.shiftsCaret= false; + c.caretOffset= c.offset + buf.length(); + + if(commentAtStart && !commentFollows && !commentAhead) { + try { + StringBuilder content = getDeclarationLines(doc, offset); + + boolean contentAlreadyThere = (firstLineContainsText && content.toString().contains(commentContentBehindCursor.trim())); + if (content == null || content.toString().trim().length() == 0 || contentAlreadyThere) + { + buf.setLength(0); + buf.append(fgDefaultLineDelim); + buf.append(indentationWithPrefix + " "); //$NON-NLS-1$ + c.shiftsCaret= false; + c.caretOffset= c.offset + buf.length(); + } else { + if (!firstLineContainsText) + { + c.shiftsCaret= false; + c.caretOffset= c.offset + 1; + buf.setLength(0); + buf.append(" " + //$NON-NLS-1$ + indent(content, indentationWithPrefix + " ", //$NON-NLS-1$ + fgDefaultLineDelim).substring((indentationWithPrefix + " ").length())); //$NON-NLS-1$ + } + else + { + buf.append(fgDefaultLineDelim); + buf.append(indent(content, indentationWithPrefix + " ", fgDefaultLineDelim)); //$NON-NLS-1$ + } + + buf.setLength(buf.length() - fgDefaultLineDelim.length()); + } + } catch(BadLocationException ble) { + ble.printStackTrace(); + } + } + + c.text= buf.toString(); + + } catch (BadLocationException excp) { + } + } + + private StringBuilder getDeclarationLines(IDocument doc, int offset) + throws BadLocationException { + IASTDeclaration dec= null; + IASTTranslationUnit ast= getAST(); + + if(ast != null) { + dec= findFollowingDeclaration(ast, offset); + if(dec == null) { + IASTNodeSelector ans= ast.getNodeSelector(ast.getFilePath()); + IASTNode node= ans.findEnclosingNode(offset, 0); + if(node instanceof IASTDeclaration) { + dec= (IASTDeclaration) node; + } + } + } + + if(dec!=null) { + ITypedRegion partition= TextUtilities.getPartition(doc, ICPartitions.C_PARTITIONING /* this! */, offset, false); + return customizeAfterNewLineForDeclaration(doc, dec, partition); + } + return null; + } + + private String getCommentPrefix(String indent) throws BadLocationException { + if (indent.endsWith(SLASH_COMMENT)) + { + return SLASH_COMMENT; + } + else + { + return EXCL_COMMENT; + } + } + + /** + * Returns the range of the comment prefix on the given line in + * document. The prefix greedily matches the following regex + * pattern: \s*\/\/[\/!], that is, any number of whitespace + * characters, followed by an comment ('///' or '//!'). + * + * @param document the document to which line refers + * @param line the line from which to extract the prefix range + * @return an IRegion describing the range of the prefix on + * the given line + * @throws BadLocationException if accessing the document fails + */ + protected static IRegion findPrefixRange(IDocument document, IRegion line) throws BadLocationException { + int lineOffset= line.getOffset(); + int lineEnd= lineOffset + line.getLength(); + int indentEnd= findEndOfWhiteSpaceAt(document, lineOffset, lineEnd); + if (indentEnd < lineEnd-2 && document.getChar(indentEnd) == '/' && document.getChar(indentEnd+1) == '/' && ( + document.getChar(indentEnd+2) == '/' || document.getChar(indentEnd+2) == '!')) { + indentEnd += 3; + } + return new Region(lineOffset, indentEnd - lineOffset); + } + +} diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/text/doctools/doxygen/DoxygenSingleConfiguration.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/text/doctools/doxygen/DoxygenSingleConfiguration.java index b412f893f38..42a4fba0461 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/text/doctools/doxygen/DoxygenSingleConfiguration.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/text/doctools/doxygen/DoxygenSingleConfiguration.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2008, 2011 Symbian Software Systems and others. + * Copyright (c) 2008, 2015 Symbian 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 @@ -11,7 +11,6 @@ package org.eclipse.cdt.ui.text.doctools.doxygen; import org.eclipse.jface.text.BadLocationException; -import org.eclipse.jface.text.DefaultIndentLineAutoEditStrategy; import org.eclipse.jface.text.IAutoEditStrategy; import org.eclipse.jface.text.IDocument; @@ -50,7 +49,7 @@ public class DoxygenSingleConfiguration extends AbstractGenericTagDocCommentView */ @Override public IAutoEditStrategy createAutoEditStrategy() { - return new DefaultIndentLineAutoEditStrategy(); + return new DoxygenSingleAutoEditStrategy(); } /*