mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-04-23 22:52:11 +02:00
Fix for Bug 48339 - Auto comment code odd behaviour
* Adds CAutoIndentTest to AutomatedTestSuite
This commit is contained in:
parent
328e4c08f1
commit
188d10797d
4 changed files with 314 additions and 16 deletions
|
@ -7,12 +7,14 @@
|
|||
*
|
||||
* Contributors:
|
||||
* IBM - Initial API and implementation
|
||||
* Anton Leherbauer (Wind River Systems) - Fixed bug 48339
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.ui.tests;
|
||||
|
||||
import junit.framework.Test;
|
||||
import junit.framework.TestSuite;
|
||||
|
||||
import org.eclipse.cdt.ui.tests.text.CAutoIndentTest;
|
||||
import org.eclipse.cdt.ui.tests.text.NumberRuleTest;
|
||||
import org.eclipse.cdt.ui.tests.text.contentassist.CompletionFailedTest_MemberReference_Arrow_Prefix2;
|
||||
import org.eclipse.cdt.ui.tests.text.contentassist.CompletionTest_ArgumentType_NoPrefix;
|
||||
|
@ -81,6 +83,7 @@ public class AutomatedSuite extends TestSuite {
|
|||
// Success Tests
|
||||
//addTest(PartitionTokenScannerTest.suite());
|
||||
addTest(NumberRuleTest.suite());
|
||||
addTest(CAutoIndentTest.suite());
|
||||
// completion tests
|
||||
addTest(CompletionTest_FieldType_Prefix.suite());
|
||||
addTest(CompletionTest_FieldType_NoPrefix.suite());
|
||||
|
|
|
@ -0,0 +1,251 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2006 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
|
||||
*******************************************************************************/
|
||||
|
||||
package org.eclipse.cdt.ui.tests.text;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import junit.framework.Test;
|
||||
import junit.framework.TestCase;
|
||||
import junit.framework.TestSuite;
|
||||
|
||||
import org.eclipse.cdt.internal.ui.text.CAutoIndentStrategy;
|
||||
import org.eclipse.cdt.internal.ui.text.CCommentAutoIndentStrategy;
|
||||
import org.eclipse.cdt.internal.ui.text.CTextTools;
|
||||
import org.eclipse.cdt.internal.ui.text.ICPartitions;
|
||||
import org.eclipse.cdt.ui.CUIPlugin;
|
||||
import org.eclipse.core.runtime.CoreException;
|
||||
import org.eclipse.jface.text.BadLocationException;
|
||||
import org.eclipse.jface.text.Document;
|
||||
import org.eclipse.jface.text.DocumentCommand;
|
||||
import org.eclipse.jface.text.IAutoEditStrategy;
|
||||
import org.eclipse.jface.text.IDocument;
|
||||
import org.eclipse.jface.text.IRegion;
|
||||
import org.eclipse.jface.text.TextUtilities;
|
||||
|
||||
/**
|
||||
* Testing the auto indent strategies.
|
||||
*/
|
||||
public class CAutoIndentTest extends TestCase {
|
||||
|
||||
/**
|
||||
* Helper class to test the auto-edit strategies on a document.
|
||||
*/
|
||||
static class AutoEditTester {
|
||||
|
||||
private Map fStrategyMap = new HashMap();
|
||||
private IDocument fDoc;
|
||||
private String fPartitioning;
|
||||
private int fCaretOffset;
|
||||
|
||||
public AutoEditTester(IDocument doc, String partitioning) {
|
||||
super();
|
||||
fDoc = doc;
|
||||
fPartitioning = partitioning;
|
||||
}
|
||||
|
||||
public void setAutoEditStrategy(String contentType, IAutoEditStrategy aes) {
|
||||
fStrategyMap.put(contentType, aes);
|
||||
}
|
||||
|
||||
public IAutoEditStrategy getAutoEditStrategy(String contentType) {
|
||||
return (IAutoEditStrategy)fStrategyMap.get(contentType);
|
||||
}
|
||||
|
||||
public void type(String text) throws BadLocationException {
|
||||
for (int i = 0; i < text.length(); ++i) {
|
||||
type(text.charAt(i));
|
||||
}
|
||||
}
|
||||
|
||||
public void type(char c) throws BadLocationException {
|
||||
TestDocumentCommand command = new TestDocumentCommand(fCaretOffset, 0, new String(new char[] { c }));
|
||||
customizeDocumentCommand(command);
|
||||
fCaretOffset += command.exec(fDoc);
|
||||
}
|
||||
|
||||
private void customizeDocumentCommand(TestDocumentCommand command) throws BadLocationException {
|
||||
IAutoEditStrategy aes = getAutoEditStrategy(getContentType());
|
||||
if (aes != null) {
|
||||
aes.customizeDocumentCommand(fDoc, command);
|
||||
}
|
||||
}
|
||||
|
||||
public void type(int offset, String text) throws BadLocationException {
|
||||
fCaretOffset = offset;
|
||||
type(text);
|
||||
}
|
||||
|
||||
public void type(int offset, char c) throws BadLocationException {
|
||||
fCaretOffset = offset;
|
||||
type(c);
|
||||
}
|
||||
|
||||
public void paste(String text) throws BadLocationException {
|
||||
TestDocumentCommand command = new TestDocumentCommand(fCaretOffset, 0, text);
|
||||
customizeDocumentCommand(command);
|
||||
fCaretOffset += command.exec(fDoc);
|
||||
}
|
||||
|
||||
public void paste(int offset, String text) throws BadLocationException {
|
||||
fCaretOffset = offset;
|
||||
paste(text);
|
||||
}
|
||||
|
||||
public void backspace(int n) throws BadLocationException {
|
||||
for (int i=0; i<n; ++i) {
|
||||
backspace();
|
||||
}
|
||||
}
|
||||
public void backspace() throws BadLocationException {
|
||||
TestDocumentCommand command = new TestDocumentCommand(fCaretOffset-1, 1, ""); //$NON-NLS-1$
|
||||
customizeDocumentCommand(command);
|
||||
fCaretOffset += command.exec(fDoc);
|
||||
}
|
||||
|
||||
public int getCaretOffset() {
|
||||
return fCaretOffset;
|
||||
}
|
||||
|
||||
public int getCaretLine() throws BadLocationException {
|
||||
return fDoc.getLineOfOffset(fCaretOffset);
|
||||
}
|
||||
|
||||
public int getCaretColumn() throws BadLocationException {
|
||||
IRegion region = fDoc.getLineInformationOfOffset(fCaretOffset);
|
||||
return fCaretOffset - region.getOffset();
|
||||
}
|
||||
|
||||
public char getChar() throws BadLocationException {
|
||||
return getChar(0);
|
||||
}
|
||||
|
||||
public char getChar(int i) throws BadLocationException {
|
||||
return fDoc.getChar(fCaretOffset+i);
|
||||
}
|
||||
|
||||
public String getLine() throws BadLocationException {
|
||||
return getLine(0);
|
||||
}
|
||||
|
||||
public String getLine(int i) throws BadLocationException {
|
||||
IRegion region = fDoc.getLineInformation(getCaretLine()+i);
|
||||
return fDoc.get(region.getOffset(), region.getLength());
|
||||
}
|
||||
|
||||
public String getContentType() throws BadLocationException {
|
||||
return getContentType(0);
|
||||
}
|
||||
|
||||
public String getContentType(int i) throws BadLocationException {
|
||||
return TextUtilities.getContentType(fDoc, fPartitioning, fCaretOffset+i, false);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A DocumentCommand with public constructor and exec method.
|
||||
*/
|
||||
static class TestDocumentCommand extends DocumentCommand {
|
||||
|
||||
public TestDocumentCommand(int offset, int length, String text) {
|
||||
super();
|
||||
doit = true;
|
||||
this.text = text;
|
||||
|
||||
this.offset = offset;
|
||||
this.length = length;
|
||||
|
||||
owner = null;
|
||||
caretOffset = -1;
|
||||
|
||||
}
|
||||
|
||||
public int exec(IDocument doc) throws BadLocationException {
|
||||
doc.replace(offset, length, text);
|
||||
return text.length() - length;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param name
|
||||
*/
|
||||
public CAutoIndentTest(String name) {
|
||||
super(name);
|
||||
}
|
||||
|
||||
public static Test suite() {
|
||||
return new TestSuite(CAutoIndentTest.class);
|
||||
}
|
||||
|
||||
private AutoEditTester createAutoEditTester() {
|
||||
CTextTools textTools = CUIPlugin.getDefault().getTextTools();
|
||||
IDocument doc = new Document();
|
||||
textTools.setupCDocument(doc);
|
||||
AutoEditTester tester = new AutoEditTester(doc, textTools.getDocumentPartitioning());
|
||||
tester.setAutoEditStrategy(IDocument.DEFAULT_CONTENT_TYPE, new CAutoIndentStrategy());
|
||||
tester.setAutoEditStrategy(ICPartitions.C_MULTILINE_COMMENT, new CCommentAutoIndentStrategy());
|
||||
return tester;
|
||||
}
|
||||
|
||||
public void testCAutoIndent() throws IOException, CoreException, BadLocationException {
|
||||
AutoEditTester tester = createAutoEditTester(); //$NON-NLS-1$
|
||||
tester.type("void main() {\n"); //$NON-NLS-1$
|
||||
assertEquals(1, tester.getCaretLine());
|
||||
assertEquals(1, tester.getCaretColumn());
|
||||
tester.type("}\n"); //$NON-NLS-1$
|
||||
assertEquals(2, tester.getCaretLine());
|
||||
assertEquals(0, tester.getCaretColumn());
|
||||
}
|
||||
|
||||
public void testDefaultAutoIndent() throws IOException, CoreException, BadLocationException {
|
||||
AutoEditTester tester = createAutoEditTester(); //$NON-NLS-1$
|
||||
tester.type(" initial indent=3\n"); //$NON-NLS-1$
|
||||
assertEquals(1, tester.getCaretLine());
|
||||
assertEquals(3, tester.getCaretColumn());
|
||||
tester.type("indent=3\n"); //$NON-NLS-1$
|
||||
assertEquals(2, tester.getCaretLine());
|
||||
assertEquals(3, tester.getCaretColumn());
|
||||
tester.backspace();
|
||||
tester.type("indent=2\n"); //$NON-NLS-1$
|
||||
assertEquals(3, tester.getCaretLine());
|
||||
assertEquals(2, tester.getCaretColumn());
|
||||
tester.backspace();
|
||||
tester.backspace();
|
||||
tester.type("indent=0\n"); //$NON-NLS-1$
|
||||
assertEquals(4, tester.getCaretLine());
|
||||
assertEquals(0, tester.getCaretColumn());
|
||||
tester.type("\n"); //$NON-NLS-1$
|
||||
assertEquals(5, tester.getCaretLine());
|
||||
assertEquals(0, tester.getCaretColumn());
|
||||
}
|
||||
|
||||
public void testCCommentAutoIndent() throws IOException, CoreException, BadLocationException {
|
||||
AutoEditTester tester = createAutoEditTester(); //$NON-NLS-1$
|
||||
tester.type("/*\n"); //$NON-NLS-1$
|
||||
assertEquals(ICPartitions.C_MULTILINE_COMMENT, tester.getContentType(-1));
|
||||
assertEquals(1, tester.getCaretLine());
|
||||
assertEquals(3, tester.getCaretColumn());
|
||||
assertEquals(" * ", tester.getLine()); //$NON-NLS-1$
|
||||
tester.type('\n');
|
||||
assertEquals(" * ", tester.getLine()); //$NON-NLS-1$
|
||||
tester.type('/');
|
||||
assertEquals(" */", tester.getLine()); //$NON-NLS-1$
|
||||
tester.type('\n');
|
||||
assertEquals(3, tester.getCaretLine());
|
||||
// TODO: indent is one space - should be no indent
|
||||
// assertEquals("", tester.getLine()); //$NON-NLS-1$
|
||||
// assertEquals(0, tester.getCaretColumn());
|
||||
}
|
||||
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2000 2005 IBM Corporation and others.
|
||||
* Copyright (c) 2000, 2006 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
|
||||
|
@ -8,6 +8,7 @@
|
|||
* Contributors:
|
||||
* IBM Corporation - initial API and implementation
|
||||
* QNX Software System
|
||||
* Anton Leherbauer (Wind River Systems) - Fixed bug 48339
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.internal.ui.text;
|
||||
|
||||
|
@ -24,6 +25,7 @@ import org.eclipse.cdt.ui.CUIPlugin;
|
|||
*/
|
||||
public class CAutoIndentStrategy extends DefaultIndentLineAutoEditStrategy {
|
||||
|
||||
private final static String MULTILINE_COMMENT_CLOSE = "*/"; //$NON-NLS-1$
|
||||
|
||||
public CAutoIndentStrategy() {
|
||||
}
|
||||
|
@ -221,10 +223,41 @@ public class CAutoIndentStrategy extends DefaultIndentLineAutoEditStrategy {
|
|||
* @see IAutoIndentStrategy#customizeDocumentCommand
|
||||
*/
|
||||
public void customizeDocumentCommand(IDocument d, DocumentCommand c) {
|
||||
if (c.length == 0 && c.text != null && endsWithDelimiter(d, c.text))
|
||||
smartIndentAfterNewLine(d, c);
|
||||
else if ("}".equals(c.text)) { //$NON-NLS-1$
|
||||
if (c.length == 0 && c.text != null && endsWithDelimiter(d, c.text)) {
|
||||
if (isAppendToOpenMultilineComment(d, c)) {
|
||||
// special case: multi-line comment at end of document (bug 48339)
|
||||
CCommentAutoIndentStrategy.commentIndentAfterNewLine(d, c);
|
||||
} else {
|
||||
smartIndentAfterNewLine(d, c);
|
||||
}
|
||||
} else if ("}".equals(c.text)) { //$NON-NLS-1$
|
||||
smartInsertAfterBracket(d, c);
|
||||
}
|
||||
else if ("/".equals(c.text) && isAppendToOpenMultilineComment(d, c)) { //$NON-NLS-1$
|
||||
// special case: multi-line comment at end of document (bug 48339)
|
||||
CCommentAutoIndentStrategy.commentIndentForCommentEnd(d, c);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check, if the command appends to an open multi-line comment.
|
||||
* @param d the document
|
||||
* @param c the document command
|
||||
* @return true, if the command appends to an open multi-line comment.
|
||||
*/
|
||||
static boolean isAppendToOpenMultilineComment(IDocument d, DocumentCommand c) {
|
||||
if (d.getLength() >= 2 && c.offset == d.getLength()) {
|
||||
try {
|
||||
String partitioning = CUIPlugin.getDefault().getTextTools().getDocumentPartitioning();
|
||||
String contentType = org.eclipse.jface.text.TextUtilities.getContentType(d, partitioning, c.offset - 1, false);
|
||||
if (ICPartitions.C_MULTILINE_COMMENT.equals(contentType)) {
|
||||
return !d.get(c.offset - 2, 2).equals(MULTILINE_COMMENT_CLOSE);
|
||||
}
|
||||
} catch (BadLocationException exc) {
|
||||
// see below
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2000 2005 IBM Corporation and others.
|
||||
* Copyright (c) 2000, 2006 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
|
||||
|
@ -8,6 +8,7 @@
|
|||
* Contributors:
|
||||
* IBM Corporation - initial API and implementation
|
||||
* QNX Software System
|
||||
* Anton Leherbauer (Wind River Systems) - Fixed bug 48339
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.internal.ui.text;
|
||||
|
||||
|
@ -18,7 +19,7 @@ import org.eclipse.jface.text.IDocument;
|
|||
import org.eclipse.jface.text.IRegion;
|
||||
|
||||
/**
|
||||
* Auto indent strategy for java doc comments
|
||||
* Auto indent strategy for C/C++ multiline comments
|
||||
*/
|
||||
public class CCommentAutoIndentStrategy extends DefaultIndentLineAutoEditStrategy {
|
||||
|
||||
|
@ -40,25 +41,24 @@ public class CCommentAutoIndentStrategy extends DefaultIndentLineAutoEditStrateg
|
|||
}
|
||||
|
||||
/**
|
||||
* Copies the indentation of the previous line and add a star
|
||||
* If the javadoc just started on tis line add also a blank
|
||||
* Copies the indentation of the previous line and adds a star.
|
||||
* If the comment just started on this line adds also a blank.
|
||||
*
|
||||
* @param d the document to work on
|
||||
* @param c the command to deal with
|
||||
*/
|
||||
private void jdocIndentAfterNewLine(IDocument d, DocumentCommand c) {
|
||||
static void commentIndentAfterNewLine(IDocument d, DocumentCommand c) {
|
||||
|
||||
if (c.offset == -1 || d.getLength() == 0)
|
||||
return;
|
||||
|
||||
try {
|
||||
// find start of line
|
||||
int p= (c.offset == d.getLength() ? c.offset - 1 : c.offset);
|
||||
IRegion info= d.getLineInformationOfOffset(p);
|
||||
IRegion info= d.getLineInformationOfOffset(c.offset);
|
||||
int start= info.getOffset();
|
||||
|
||||
// find white spaces
|
||||
int end= findEndOfWhiteSpace(d, start, c.offset);
|
||||
int end= findEndOfWhiteSpaceAt(d, start, c.offset);
|
||||
|
||||
StringBuffer buf= new StringBuffer(c.text);
|
||||
if (end >= start) { // 1GEYL1R: ITPJUI:ALL - java doc edit smartness not work for class comments
|
||||
|
@ -66,7 +66,7 @@ public class CCommentAutoIndentStrategy extends DefaultIndentLineAutoEditStrateg
|
|||
buf.append(d.get(start, end - start));
|
||||
if (end < c.offset) {
|
||||
if (d.getChar(end) == '/') {
|
||||
// javadoc started on this line
|
||||
// comment started on this line
|
||||
buf.append(" * "); //$NON-NLS-1$
|
||||
} else if (d.getChar(end) == '*') {
|
||||
buf.append("* "); //$NON-NLS-1$
|
||||
|
@ -82,7 +82,18 @@ public class CCommentAutoIndentStrategy extends DefaultIndentLineAutoEditStrateg
|
|||
}
|
||||
}
|
||||
|
||||
protected void jdocIndentForCommentEnd(IDocument d, DocumentCommand c) {
|
||||
static int findEndOfWhiteSpaceAt(IDocument document, int offset, int end) throws BadLocationException {
|
||||
while (offset < end) {
|
||||
char c= document.getChar(offset);
|
||||
if (c != ' ' && c != '\t') {
|
||||
return offset;
|
||||
}
|
||||
offset++;
|
||||
}
|
||||
return end;
|
||||
}
|
||||
|
||||
static void commentIndentForCommentEnd(IDocument d, DocumentCommand c) {
|
||||
if (c.offset < 2 || d.getLength() == 0) {
|
||||
return;
|
||||
}
|
||||
|
@ -102,9 +113,9 @@ public class CCommentAutoIndentStrategy extends DefaultIndentLineAutoEditStrateg
|
|||
*/
|
||||
public void customizeDocumentCommand(IDocument d, DocumentCommand c) {
|
||||
if (c.length == 0 && c.text != null && endsWithDelimiter(d, c.text))
|
||||
jdocIndentAfterNewLine(d, c);
|
||||
commentIndentAfterNewLine(d, c);
|
||||
else if ("/".equals(c.text)) { //$NON-NLS-1$
|
||||
jdocIndentForCommentEnd(d, c);
|
||||
commentIndentForCommentEnd(d, c);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue