1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-04-29 19:45:01 +02:00

Add smart edit and indenter tests

This commit is contained in:
Anton Leherbauer 2006-10-04 10:44:31 +00:00
parent 8c9b5d9416
commit 07031919f1
16 changed files with 1844 additions and 46 deletions

View file

@ -0,0 +1,25 @@
/* This is sample code to test the indenter */
class Complex {
private:
float re;
float im;
public:
Complex(float re, float im) :
re(re), im(im) {}
float GetRe()
{
return re;
}
float GetIm() {
return im;
}
void Set(float r, float i);
void SetRe(float r);
void SetIm(float i);
void Print();
};

View file

@ -0,0 +1,25 @@
/* This is sample code to test the indenter */
class Complex {
private:
float re;
float im;
public:
Complex(float re, float im) :
re(re), im(im) {}
float GetRe()
{
return re;
}
float GetIm() {
return im;
}
void Set(float r, float i);
void SetRe(float r);
void SetIm(float i);
void Print();
};

View file

@ -0,0 +1,48 @@
#include <Simple.h>
const SimpleStruct simpleStruct =
{
1
, "mySimple"
, 0.1232
};
#define SIZEOF( A, B ) sizeof( A.B )
const OtherStruct array[] =
{
{
#if FOO
"foo"
#else
"bar"
#endif
, SIZEOF( simpleStruct, num )
, &t_int
, 0
}
, {
"name"
, SIZEOF( simpleStruct, floatnum )
, &t_float
, 1
}
};
void SimpleStruct_construct(
struct SimpleStruct * const this )
{
// single line
this->num = 1;
this->name = "boo";
this->floatNum = 1.5;
}
int ConnectParams_doSomething( const struct SimpleStruct * const this )
{
/*
* multiline
*/
return 1;
}

View file

@ -0,0 +1,48 @@
#include <Simple.h>
const SimpleStruct simpleStruct =
{
1
, "mySimple"
, 0.1232
};
#define SIZEOF( A, B ) sizeof( A.B )
const OtherStruct array[] =
{
{
#if FOO
"foo"
#else
"bar"
#endif
, SIZEOF( simpleStruct, num )
, &t_int
, 0
}
, {
"name"
, SIZEOF( simpleStruct, floatnum )
, &t_float
, 1
}
};
void SimpleStruct_construct(
struct SimpleStruct * const this )
{
// single line
this->num = 1;
this->name = "boo";
this->floatNum = 1.5;
}
int ConnectParams_doSomething( const struct SimpleStruct * const this )
{
/*
* multiline
*/
return 1;
}

View file

@ -0,0 +1,80 @@
#include <cppunit/tools/StringTools.h>
#include <cppunit/portability/Stream.h>
#include <algorithm>
CPPUNIT_NS_BEGIN
std::string
StringTools::toString( int value )
{
OStringStream stream;
stream << value;
return stream.str();
}
std::string
StringTools::toString( double value )
{
OStringStream stream;
stream << value;
return stream.str();
}
StringTools::Strings
StringTools::split( const std::string &text,
char separator )
{
Strings splittedText;
std::string::const_iterator itStart = text.begin();
while ( !text.empty() )
{
std::string::const_iterator itSeparator = std::find( itStart,
text.end(),
separator );
splittedText.push_back( text.substr( itStart - text.begin(),
itSeparator - itStart ) );
if ( itSeparator == text.end() )
break;
itStart = itSeparator +1;
}
return splittedText;
}
std::string
StringTools::wrap( const std::string &text,
int wrapColumn )
{
const char lineBreak = '\n';
Strings lines = split( text, lineBreak );
std::string wrapped;
for ( Strings::const_iterator it = lines.begin(); it != lines.end(); ++it )
{
if ( it != lines.begin() )
wrapped += lineBreak;
const std::string &line = *it;
unsigned int index =0;
while ( index < line.length() )
{
std::string lineSlice( line.substr( index, wrapColumn ) );
wrapped += lineSlice;
index += wrapColumn;
if ( index < line.length() )
wrapped += lineBreak;
}
}
return wrapped;
}
CPPUNIT_NS_END

View file

@ -0,0 +1,80 @@
#include <cppunit/tools/StringTools.h>
#include <cppunit/portability/Stream.h>
#include <algorithm>
CPPUNIT_NS_BEGIN
std::string
StringTools::toString( int value )
{
OStringStream stream;
stream << value;
return stream.str();
}
std::string
StringTools::toString( double value )
{
OStringStream stream;
stream << value;
return stream.str();
}
StringTools::Strings
StringTools::split( const std::string &text,
char separator )
{
Strings splittedText;
std::string::const_iterator itStart = text.begin();
while ( !text.empty() )
{
std::string::const_iterator itSeparator = std::find( itStart,
text.end(),
separator );
splittedText.push_back( text.substr( itStart - text.begin(),
itSeparator - itStart ) );
if ( itSeparator == text.end() )
break;
itStart = itSeparator +1;
}
return splittedText;
}
std::string
StringTools::wrap( const std::string &text,
int wrapColumn )
{
const char lineBreak = '\n';
Strings lines = split( text, lineBreak );
std::string wrapped;
for ( Strings::const_iterator it = lines.begin(); it != lines.end(); ++it )
{
if ( it != lines.begin() )
wrapped += lineBreak;
const std::string &line = *it;
unsigned int index =0;
while ( index < line.length() )
{
std::string lineSlice( line.substr( index, wrapColumn ) );
wrapped += lineSlice;
index += wrapColumn;
if ( index < line.length() )
wrapped += lineBreak;
}
}
return wrapped;
}
CPPUNIT_NS_END

View file

@ -0,0 +1,428 @@
/*******************************************************************************
* 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
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
* Anton Leherbauer (Wind River Systems)
*******************************************************************************/
package org.eclipse.cdt.ui.tests.text;
import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;
import org.eclipse.core.resources.IContainer;
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.NullProgressMonitor;
import org.eclipse.core.runtime.Path;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.ITextSelection;
import org.eclipse.jface.text.TextSelection;
import org.eclipse.jface.text.link.ILinkedModeListener;
import org.eclipse.jface.text.link.LinkedModeModel;
import org.eclipse.jface.text.link.LinkedPosition;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.StyledText;
import org.eclipse.swt.widgets.Event;
import org.eclipse.ui.PartInitException;
import org.eclipse.cdt.core.model.CModelException;
import org.eclipse.cdt.core.model.ICContainer;
import org.eclipse.cdt.core.model.ICProject;
import org.eclipse.cdt.core.testplugin.CProjectHelper;
import org.eclipse.cdt.ui.CUIPlugin;
import org.eclipse.cdt.ui.PreferenceConstants;
import org.eclipse.cdt.internal.ui.editor.CEditor;
/**
* Tests the automatic bracket insertion feature of the CEditor. Also tests
* linked mode along the way.
*/
public class BracketInserterTest extends TestCase {
private static final String SRC= "src";
private static final String SEP= "/";
private static final String TU_NAME= "smartedit.cpp";
private static final String TU_CONTENTS=
"#include \n" +
"class Application {\n" +
" char* string;\n" +
" int integer;\n" +
"\n" +
"public:\n" +
" static void main(int argc, char** args);\n" +
"protected:\n" +
" void foo(char** args);\n" +
"};\n" +
"\n" +
"void Application::main(int argc, char** args) {\n" +
" \n" +
"}\n" +
"void Application::foo(char** args) {\n" +
" char[] t= args[0];" +
"}\n";
// document offsets
private static final int INCLUDE_OFFSET= 9;
private static final int BODY_OFFSET= 212;
private static final int ARGS_OFFSET= 184;
private static final int BRACKETS_OFFSET= 262;
public static Test suite() {
TestSuite suite= new TestSuite(BracketInserterTest.class);
return suite;
}
private CEditor fEditor;
private StyledText fTextWidget;
private IDocument fDocument;
private Accessor fAccessor;
private ICProject fProject;
protected void setUp() throws Exception {
IPreferenceStore store= CUIPlugin.getDefault().getPreferenceStore();
store.setValue(PreferenceConstants.EDITOR_CLOSE_BRACKETS, true);
setUpProject();
setUpEditor();
}
private void setUpProject() throws CoreException {
fProject= CProjectHelper.createCProject(getName(), "bin");
ICContainer cContainer= CProjectHelper.addCContainer(fProject, SRC);
IFile file= EditorTestHelper.createFile((IContainer)cContainer.getResource(), TU_NAME, TU_CONTENTS, new NullProgressMonitor());
assertNotNull(file);
assertTrue(file.exists());
}
private void setUpEditor() {
fEditor= openCEditor(new Path(SEP + getName() + SEP + SRC + SEP + TU_NAME));
assertNotNull(fEditor);
fTextWidget= fEditor.getViewer().getTextWidget();
assertNotNull(fTextWidget);
fAccessor= new Accessor(fTextWidget, StyledText.class);
fDocument= fEditor.getDocumentProvider().getDocument(fEditor.getEditorInput());
assertNotNull(fDocument);
assertEquals(TU_CONTENTS, fDocument.get());
}
private CEditor openCEditor(IPath path) {
IFile file= ResourcesPlugin.getWorkspace().getRoot().getFile(path);
assertTrue(file != null && file.exists());
try {
return (CEditor)EditorTestHelper.openInEditor(file, true);
} catch (PartInitException e) {
fail();
return null;
}
}
protected void tearDown() throws Exception {
EditorTestHelper.closeEditor(fEditor);
fEditor= null;
if (fProject != null) {
CProjectHelper.delete(fProject);
fProject= null;
}
// reset to defaults
IPreferenceStore store= CUIPlugin.getDefault().getPreferenceStore();
store.setToDefault(PreferenceConstants.EDITOR_CLOSE_BRACKETS);
}
public void testInsertClosingParenthesis() throws BadLocationException, CModelException, CoreException, CModelException, CoreException {
setCaret(BODY_OFFSET);
type('(');
assertEquals("()", fDocument.get(BODY_OFFSET, 2));
assertSingleLinkedPosition(BODY_OFFSET + 1);
}
public void testDeletingParenthesis() throws CModelException, CoreException {
setCaret(BODY_OFFSET);
type('(');
type(SWT.BS);
assertEquals(TU_CONTENTS, fDocument.get());
assertFalse(LinkedModeModel.hasInstalledModel(fDocument));
}
public void testMultipleParenthesisInsertion() throws BadLocationException, CModelException, CoreException {
setCaret(BODY_OFFSET);
type("((((");
assertEquals("(((())))", fDocument.get(BODY_OFFSET, 8));
assertEquals(BODY_OFFSET + 4, getCaret());
assertModel(true);
}
public void testDeletingMultipleParenthesisInertion() throws BadLocationException, CModelException, CoreException {
setCaret(BODY_OFFSET);
type("((((");
// delete two levels
linkedType(SWT.BS, true, ILinkedModeListener.EXTERNAL_MODIFICATION);
linkedType(SWT.BS, true, ILinkedModeListener.EXTERNAL_MODIFICATION);
assertEquals("(())", fDocument.get(BODY_OFFSET, 4));
assertEquals(BODY_OFFSET + 2, getCaret());
// delete the second-last level
linkedType(SWT.BS, true, ILinkedModeListener.EXTERNAL_MODIFICATION);
assertEquals("()", fDocument.get(BODY_OFFSET, 2));
assertEquals(BODY_OFFSET + 1, getCaret());
// delete last level
linkedType(SWT.BS, false, ILinkedModeListener.EXTERNAL_MODIFICATION);
assertEquals(TU_CONTENTS, fDocument.get());
assertEquals(BODY_OFFSET, getCaret());
assertEquals(TU_CONTENTS, fDocument.get());
assertFalse(LinkedModeModel.hasInstalledModel(fDocument));
}
public void testNoInsertInsideText() throws BadLocationException, CModelException, CoreException {
setCaret(ARGS_OFFSET);
type('(');
assertEquals("(in", fDocument.get(ARGS_OFFSET, 3));
assertEquals(ARGS_OFFSET + 1, getCaret());
assertFalse(LinkedModeModel.hasInstalledModel(fDocument));
}
public void testInsertInsideBrackets() throws BadLocationException, CModelException, CoreException {
setCaret(BRACKETS_OFFSET);
type('(');
assertEquals("()", fDocument.get(BRACKETS_OFFSET, 2));
assertSingleLinkedPosition(BRACKETS_OFFSET + 1);
}
public void testPeerEntry() throws BadLocationException, CModelException, CoreException {
setCaret(BODY_OFFSET);
type("()");
assertEquals("()", fDocument.get(BODY_OFFSET, 2));
assertEquals(BODY_OFFSET + 2, getCaret());
assertFalse(LinkedModeModel.hasInstalledModel(fDocument));
}
public void testMultiplePeerEntry() throws BadLocationException, CModelException, CoreException {
setCaret(BODY_OFFSET);
type("((((");
linkedType(')', true, ILinkedModeListener.UPDATE_CARET);
linkedType(')', true, ILinkedModeListener.UPDATE_CARET);
linkedType(')', true, ILinkedModeListener.UPDATE_CARET);
assertEquals("(((())))", fDocument.get(BODY_OFFSET, 8));
assertEquals(BODY_OFFSET + 7, getCaret());
LinkedPosition position= assertModel(false).findPosition(new LinkedPosition(fDocument, BODY_OFFSET + 1, 0));
assertNotNull(position);
assertEquals(BODY_OFFSET + 1, position.getOffset());
assertEquals(6, position.getLength());
linkedType(')', false, ILinkedModeListener.UPDATE_CARET);
assertEquals("(((())))", fDocument.get(BODY_OFFSET, 8));
assertEquals(BODY_OFFSET + 8, getCaret());
assertFalse(LinkedModeModel.hasInstalledModel(fDocument));
}
public void testExitOnTab() throws BadLocationException, CModelException, CoreException {
setCaret(BODY_OFFSET);
type("((((");
linkedType('\t', true, ILinkedModeListener.NONE);
assertEquals("(((())))", fDocument.get(BODY_OFFSET, 8));
assertEquals(BODY_OFFSET + 5, getCaret());
linkedType('\t', true, ILinkedModeListener.NONE);
linkedType('\t', true, ILinkedModeListener.NONE);
assertEquals("(((())))", fDocument.get(BODY_OFFSET, 8));
assertEquals(BODY_OFFSET + 7, getCaret());
linkedType('\t', false, ILinkedModeListener.NONE);
assertEquals("(((())))", fDocument.get(BODY_OFFSET, 8));
assertEquals(BODY_OFFSET + 8, getCaret());
assertFalse(LinkedModeModel.hasInstalledModel(fDocument));
}
public void testExitOnReturn() throws BadLocationException, CModelException, CoreException {
setCaret(BODY_OFFSET);
type("((((");
linkedType(SWT.CR, true, ILinkedModeListener.UPDATE_CARET | ILinkedModeListener.EXIT_ALL);
assertEquals("(((())))", fDocument.get(BODY_OFFSET, 8));
assertEquals(BODY_OFFSET + 8, getCaret());
assertFalse(LinkedModeModel.hasInstalledModel(fDocument));
}
public void testExitOnEsc() throws BadLocationException, CModelException, CoreException {
setCaret(BODY_OFFSET);
type("((((");
linkedType(SWT.ESC, true, ILinkedModeListener.EXIT_ALL);
assertEquals("(((())))", fDocument.get(BODY_OFFSET, 8));
assertEquals(BODY_OFFSET + 4, getCaret());
assertFalse(LinkedModeModel.hasInstalledModel(fDocument));
}
public void testInsertClosingQuote() throws BadLocationException, CModelException, CoreException {
setCaret(BODY_OFFSET);
type('"');
assertEquals("\"\"", fDocument.get(BODY_OFFSET, 2));
assertSingleLinkedPosition(BODY_OFFSET + 1);
}
public void testPreferences() throws BadLocationException, CModelException, CoreException {
IPreferenceStore store= CUIPlugin.getDefault().getPreferenceStore();
store.setValue(PreferenceConstants.EDITOR_CLOSE_BRACKETS, false);
setCaret(BODY_OFFSET);
type('(');
assertEquals("(", fDocument.get(BODY_OFFSET, 1));
assertEquals(BODY_OFFSET + 1, getCaret());
assertFalse(LinkedModeModel.hasInstalledModel(fDocument));
}
public void testAngleBracketsAsOperator() throws Exception {
setCaret(BODY_OFFSET);
type("test<");
assertEquals("test<", fDocument.get(BODY_OFFSET, 5));
assertFalse(">".equals(fDocument.get(BODY_OFFSET + 5, 1)));
assertEquals(BODY_OFFSET + 5, getCaret());
assertFalse(LinkedModeModel.hasInstalledModel(fDocument));
}
public void testAngleBrackets() throws Exception {
setCaret(BODY_OFFSET);
type("Test<");
assertEquals("Test<>", fDocument.get(BODY_OFFSET, 6));
assertSingleLinkedPosition(BODY_OFFSET + 5);
}
public void testAngleBracketsInInclude() throws Exception {
setCaret(INCLUDE_OFFSET);
type('<');
assertEquals("#include <>", fDocument.get(INCLUDE_OFFSET - 9, 11));
assertSingleLinkedPosition(INCLUDE_OFFSET + 1);
}
/* utilities */
private void assertSingleLinkedPosition(int offset) {
assertEquals(offset, getCaret());
LinkedPosition position= assertModel(false).findPosition(new LinkedPosition(fDocument, offset, 0));
assertNotNull(position);
assertEquals(offset, position.getOffset());
assertEquals(0, position.getLength());
}
/**
* Type characters into the styled text.
*
* @param characters the characters to type
*/
private void type(CharSequence characters) {
for (int i= 0; i < characters.length(); i++)
type(characters.charAt(i), 0, 0);
}
/**
* Type a character into the styled text.
*
* @param character the character to type
*/
private void type(char character) {
type(character, 0, 0);
}
/**
* Ensure there is a linked mode and type a character into the styled text.
*
* @param character the character to type
* @param nested whether the linked mode is expected to be nested or not
* @param expectedExitFlags the expected exit flags for the current linked mode after typing the character, -1 for no exit
*/
private void linkedType(char character, boolean nested, int expectedExitFlags) {
final int[] exitFlags= { -1 };
assertModel(nested).addLinkingListener(new ILinkedModeListener() {
public void left(LinkedModeModel model, int flags) {
exitFlags[0]= flags;
}
public void resume(LinkedModeModel model, int flags) {
}
public void suspend(LinkedModeModel model) {
}
});
type(character, 0, 0);
assertEquals(expectedExitFlags, exitFlags[0]);
}
private LinkedModeModel assertModel(boolean nested) {
LinkedModeModel model= LinkedModeModel.getModel(fDocument, 0); // offset does not matter
assertNotNull(model);
assertEquals(nested, model.isNested());
return model;
}
/**
* Type a character into the styled text.
*
* @param character the character to type
* @param keyCode the key code
* @param stateMask the state mask
*/
private void type(char character, int keyCode, int stateMask) {
Event event= new Event();
event.character= character;
event.keyCode= keyCode;
event.stateMask= stateMask;
fAccessor.invoke("handleKeyDown", new Object[] {event});
new DisplayHelper() {
protected boolean condition() {
return false;
}
}.waitForCondition(EditorTestHelper.getActiveDisplay(), 200);
}
private int getCaret() {
return ((ITextSelection) fEditor.getSelectionProvider().getSelection()).getOffset();
}
private void setCaret(int offset) {
fEditor.getSelectionProvider().setSelection(new TextSelection(offset, 0));
int newOffset= ((ITextSelection)fEditor.getSelectionProvider().getSelection()).getOffset();
assertEquals(offset, newOffset);
}
}

View file

@ -0,0 +1,881 @@
/*******************************************************************************
* 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
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
* Anton Leherbauer (Wind River Systems)
*******************************************************************************/
package org.eclipse.cdt.ui.tests.text;
import java.util.HashMap;
import junit.framework.Assert;
import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;
import org.eclipse.jface.text.Document;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.rules.FastPartitioner;
import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.formatter.DefaultCodeFormatterConstants;
import org.eclipse.cdt.ui.text.ICPartitions;
import org.eclipse.cdt.internal.ui.text.CHeuristicScanner;
import org.eclipse.cdt.internal.ui.text.CIndenter;
import org.eclipse.cdt.internal.ui.text.FastCPartitionScanner;
/**
* CHeuristicScannerTest.
* Derived from JDT.
*/
public class CHeuristicScannerTest extends TestCase {
private FastPartitioner fPartitioner;
private Document fDocument;
private CIndenter fScanner;
private CHeuristicScanner fHeuristicScanner;
public static Test suite() {
return new TestSuite(CHeuristicScannerTest.class);
}
/*
* @see junit.framework.TestCase#setUp()
*/
protected void setUp() {
if (CCorePlugin.getDefault() != null) {
HashMap options= CCorePlugin.getDefaultOptions();
options.put(DefaultCodeFormatterConstants.FORMATTER_TAB_CHAR, CCorePlugin.TAB);
options.put(DefaultCodeFormatterConstants.FORMATTER_TAB_SIZE, "4");
final String indentOnColumn= DefaultCodeFormatterConstants.createAlignmentValue(false, DefaultCodeFormatterConstants.WRAP_NO_SPLIT, DefaultCodeFormatterConstants.INDENT_ON_COLUMN);
options.put(DefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_PARAMETERS_IN_METHOD_DECLARATION, indentOnColumn);
options.put(DefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_EXPRESSIONS_IN_ARRAY_INITIALIZER, indentOnColumn);
options.put(DefaultCodeFormatterConstants.FORMATTER_CONTINUATION_INDENTATION, "1");
CCorePlugin.setOptions(options);
}
fDocument= new Document();
String[] types= new String[] {
ICPartitions.C_MULTI_LINE_COMMENT,
ICPartitions.C_SINGLE_LINE_COMMENT,
ICPartitions.C_STRING,
ICPartitions.C_CHARACTER,
ICPartitions.C_PREPROCESSOR,
IDocument.DEFAULT_CONTENT_TYPE
};
fPartitioner= new FastPartitioner(new FastCPartitionScanner(), types);
fPartitioner.connect(fDocument);
fDocument.setDocumentPartitioner(ICPartitions.C_PARTITIONING, fPartitioner);
fHeuristicScanner= new CHeuristicScanner(fDocument);
fScanner= new CIndenter(fDocument, fHeuristicScanner);
}
/*
* @see junit.framework.TestCase#tearDown()
*/
protected void tearDown() throws Exception {
fDocument.setDocumentPartitioner(ICPartitions.C_PARTITIONING, null);
fPartitioner.disconnect();
fPartitioner= null;
fDocument= null;
if (CCorePlugin.getDefault() != null) {
CCorePlugin.setOptions(CCorePlugin.getDefaultOptions());
}
}
public void testPrevIndentationUnit1() {
fDocument.set("\tint a;\n" +
"\tif (true)\n" +
"");
int pos= fScanner.findReferencePosition(18);
Assert.assertEquals(9, pos);
}
public void testPrevIndentationUnit2() {
fDocument.set("\tint a;\n" +
"\tif (true)\n" +
"\t\treturn a");
int pos= fScanner.findReferencePosition(28);
Assert.assertEquals(21, pos);
}
public void testPrevIndentationUnit4() {
fDocument.set("\tint a;\n" +
"\tif (true)\n" +
"\t\treturn a\n" +
"");
int pos= fScanner.findReferencePosition(29);
Assert.assertEquals(28, pos);
}
public void testPrevIndentationUnit5() {
fDocument.set("\tint a;\n" +
"\tif (true)\n" +
"\t\treturn a;\n" +
"");
int pos= fScanner.findReferencePosition(30);
Assert.assertEquals(9, pos);
}
public void testPrevIndentationUnit6() {
// method definition
fDocument.set("\tvoid proc (int par1, int par2\n");
int pos= fScanner.findReferencePosition(30);
Assert.assertEquals(12, pos);
}
public void testPrevIndentationUnit7() {
// for with semis
fDocument.set("\tvoid proc (int par1, int par2) {\n" +
"\t\t\n" +
"\t\tfor (int i= 4; i < 33; i++) \n" +
"");
int pos= fScanner.findReferencePosition(fDocument.getLength());
Assert.assertEquals(39, pos);
}
public void testPrevIndentationUnit8() {
// TODO this is mean - comment at indentation spot
fDocument.set("\t/* comment */ void proc (int par1, int par2) {\n");
int pos= fScanner.findReferencePosition(fDocument.getLength());
// Assert.assertEquals(1, pos);
Assert.assertEquals(15, pos);
}
public void testPrevIndentationUnit9() {
// block
fDocument.set("\tvoid proc (int par1, int par2) {\n" +
"\t\t\n" +
"\t\tfor (int i= 4; i < 33; i++) {\n" +
"\t\t}\n" +
"\t\t\n" +
"\t\tint i;\n");
int pos= fScanner.findReferencePosition(fDocument.getLength());
Assert.assertEquals(fDocument.getLength() - 7, pos);
}
public void testPrevIndentationUnit10() {
// if else
fDocument.set("\tvoid proc (int par1, int par2) {\n" +
"\t\t\n" +
"\t\tif (condition()) {\n" +
"\t\t\tcode();\n" +
"\t\t} else {\n" +
"\t\t\totherCode();\n" +
"\t\t}\n" +
"");
int pos= fScanner.findReferencePosition(fDocument.getLength());
Assert.assertEquals(39, pos);
}
public void testPrevIndentationUnit11() {
// inside else block
fDocument.set("\tvoid proc (int par1, int par2) {\n" +
"\t\t\n" +
"\t\tif (condition()) {\n" +
"\t\t\tcode();\n" +
"\t\t} else {\n" +
"\t\t\totherCode();\n" +
"\t\t" +
"");
int pos= fScanner.findReferencePosition(fDocument.getLength());
Assert.assertEquals(83, pos);
}
public void testPrevIndentation1() {
fDocument.set("\tint a;\n" +
"\tif (true)\n" +
"");
String indent= fScanner.getReferenceIndentation(18).toString();
Assert.assertEquals("\t", indent);
}
public void testPrevIndentation2() {
fDocument.set("\tint a;\n" +
"\tif (true)\n" +
"\t\treturn a");
String indent= fScanner.getReferenceIndentation(28).toString();
Assert.assertEquals("\t\t", indent);
}
public void testPrevIndentation3() {
fDocument.set("\tint a;\n" +
"\tif (true)\n" +
"\t\treturn a;");
String indent= fScanner.getReferenceIndentation(29).toString();
Assert.assertEquals("\t\t", indent);
}
public void testPrevIndentation4() {
fDocument.set("\tint a;\n" +
"\tif (true)\n" +
"\t\treturn a\n" +
"");
String indent= fScanner.getReferenceIndentation(29).toString();
Assert.assertEquals("\t\t", indent);
}
public void testPrevIndentation5() {
fDocument.set("\tint a;\n" +
"\tif (true)\n" +
"\t\treturn a;\n" +
"");
String indent= fScanner.getReferenceIndentation(30).toString();
Assert.assertEquals("\t", indent);
}
public void testPrevIndentation6() {
fDocument.set("\tvoid proc (int par1, int par2\n");
String indent= fScanner.getReferenceIndentation(30).toString();
Assert.assertEquals("\t", indent);
}
public void testPrevIndentation7() {
// for with semis
fDocument.set("\tvoid proc (int par1, int par2) {\n" +
"\t\t\n" +
"\t\tfor (int i= 4; i < 33; i++) \n" +
"");
String indent= fScanner.getReferenceIndentation(fDocument.getLength()).toString();
Assert.assertEquals("\t\t", indent);
}
public void testPrevIndentation8() {
fDocument.set("\t/* comment */ void proc (int par1, int par2) {\n");
String indent= fScanner.getReferenceIndentation(fDocument.getLength()).toString();
Assert.assertEquals("\t", indent);
}
public void testPrevIndentation9() {
// block
fDocument.set("\tvoid proc (int par1, int par2) {\n" +
"\t\t\n" +
"\t\tfor (int i= 4; i < 33; i++) {\n" +
"\t\t}\n" +
"\t\t\n" +
"\t\tint i;\n");
String indent= fScanner.getReferenceIndentation(fDocument.getLength()).toString();
Assert.assertEquals("\t\t", indent);
}
public void testPrevIndentation10() {
// else
fDocument.set("\tvoid proc (int par1, int par2) {\n" +
"\t\t\n" +
"\t\tif (condition()) {\n" +
"\t\t\tcode();\n" +
"\t\t} else {\n" +
"\t\t\totherCode();\n" +
"\t\t}\n" +
"");
String indent= fScanner.getReferenceIndentation(fDocument.getLength()).toString();
Assert.assertEquals("\t\t", indent);
}
public void testPrevIndentation11() {
// else
fDocument.set("\tvoid proc (int par1, int par2) {\n" +
"\t\t\n" +
"\t\tif (condition()) {\n" +
"\t\t\tcode();\n" +
"\t\t} else {\n" +
"\t\t\totherCode();\n" +
"\t\t" +
"");
String indent= fScanner.getReferenceIndentation(fDocument.getLength()).toString();
Assert.assertEquals("\t\t\t", indent);
}
public void testIndentation1() {
fDocument.set("\tint a;\n" +
"\tif (true)\n" +
"");
String indent= fScanner.computeIndentation(18).toString();
Assert.assertEquals("\t\t", indent);
}
public void testIndentation2() {
fDocument.set("\tint a;\n" +
"\tif (true)\n" +
"\t\treturn a");
String indent= fScanner.computeIndentation(28).toString();
Assert.assertEquals("\t\t", indent);
}
public void testIndentation3() {
fDocument.set("\tint a;\n" +
"\tif (true)\n" +
"\t\treturn a;");
String indent= fScanner.computeIndentation(29).toString();
Assert.assertEquals("\t\t", indent);
}
public void testIndentation4() {
fDocument.set("\tint a;\n" +
"\tif (true)\n" +
"\t\treturn a\n" +
"");
String indent= fScanner.computeIndentation(29).toString();
Assert.assertEquals("\t\t", indent);
}
public void testIndentation5() {
fDocument.set("\tint a;\n" +
"\tif (true)\n" +
"\t\treturn a;\n" +
"");
String indent= fScanner.computeIndentation(30).toString();
Assert.assertEquals("\t", indent);
}
public void testIndentation6() {
// parameter declaration - alignment with parenthesis
fDocument.set("\tvoid proc (int par1, int par2\n");
String indent= fScanner.computeIndentation(30).toString();
Assert.assertEquals("\t ", indent);
}
public void testIndentation6a() {
// parameter declaration - alignment with parenthesis
fDocument.set("\tvoid proc ( int par1, int par2\n");
String indent= fScanner.computeIndentation(30).toString();
Assert.assertEquals("\t ", indent);
}
public void testIndentation7() {
// for with semis
fDocument.set("\tvoid proc (int par1, int par2) {\n" +
"\t\t\n" +
"\t\tfor (int i= 4; i < 33; i++) \n" +
"");
String indent= fScanner.computeIndentation(fDocument.getLength()).toString();
Assert.assertEquals("\t\t\t", indent);
}
public void testIndentation8() {
// method definition
fDocument.set("\t/* package */ void proc (int par1, int par2) {\n");
String indent= fScanner.computeIndentation(fDocument.getLength()).toString();
Assert.assertEquals("\t\t", indent);
}
public void testIndentation9() {
// block
fDocument.set("\tvoid proc (int par1, int par2) {\n" +
"\t\t\n" +
"\t\tfor (int i= 4; i < 33; i++) {\n" +
"\t\t}\n" +
"\t\t\n" +
"\t\tint i;\n");
String indent= fScanner.computeIndentation(fDocument.getLength()).toString();
Assert.assertEquals("\t\t", indent);
}
public void testIndentation10() {
// else
fDocument.set("\tvoid proc (int par1, int par2) {\n" +
"\t\t\n" +
"\t\tif (condition()) {\n" +
"\t\t\tcode();\n" +
"\t\t} else {\n" +
"\t\t\totherCode();\n" +
"\t\t}\n" +
"");
String indent= fScanner.computeIndentation(fDocument.getLength()).toString();
Assert.assertEquals("\t\t", indent);
}
public void testIndentation11() {
// else
fDocument.set("\tvoid proc (int par1, int par2) {\n" +
"\t\t\n" +
"\t\tif (condition()) {\n" +
"\t\t\tcode();\n" +
"\t\t} else {\n" +
"\t\t\totherCode();\n" +
"\t\t" +
"");
String indent= fScanner.computeIndentation(fDocument.getLength()).toString();
Assert.assertEquals("\t\t\t", indent);
}
public void testIndentation12() {
// multi-line condition
fDocument.set("\tvoid proc (int par1, int par2) {\n" +
"\t\t\n" +
"\t\tif (condition1()\n" +
"");
String indent= fScanner.computeIndentation(fDocument.getLength()).toString();
Assert.assertEquals("\t\t\t", indent);
}
public void testIndentation13() {
// multi-line call
fDocument.set("\tvoid proc (int par1, int par2) {\n" +
"\t\t\n" +
"\t\tthis->doStuff(param1, param2,\n" +
"");
String indent= fScanner.computeIndentation(fDocument.getLength()).toString();
Assert.assertEquals("\t\t\t", indent);
}
public void testIndentation14() {
// multi-line array initializer
fDocument.set("\tvoid proc (int par1, int par2) {\n" +
"\t\t\n" +
"\t\tString[] arr= new String[] { a1, a2,\n" +
"");
String indent= fScanner.computeIndentation(fDocument.getLength()).toString();
Assert.assertEquals(" ", indent);
}
public void testIndentation15() {
// for
fDocument.set("\tfor (int i= 0; i < 10; i++) {\n" +
"\t\tbar(); bar(); // foo\n" +
"\t}\n");
String indent= fScanner.computeIndentation(fDocument.getLength()).toString();
Assert.assertEquals("\t", indent);
}
public void testIndentation16() {
// if
fDocument.set("\tif (true)\n" +
"\t\t;");
String indent= fScanner.computeIndentation(fDocument.getLength() - 1).toString();
Assert.assertEquals("\t\t", indent);
}
public void testIndentation17() {
// if
fDocument.set("\tif (true)\n" +
";");
String indent= fScanner.computeIndentation(fDocument.getLength() - 1).toString();
Assert.assertEquals("\t\t", indent);
}
public void testIndentation18() {
// if
fDocument.set("\tif (true)\n" +
"");
String indent= fScanner.computeIndentation(fDocument.getLength()).toString();
Assert.assertEquals("\t\t", indent);
}
public void testIndentation19() {
// if w/ brace right after }
fDocument.set("\tif (true) {\n" +
"\t\t}");
String indent= fScanner.computeIndentation(fDocument.getLength()).toString();
Assert.assertEquals("\t", indent);
}
public void testIndentation20() {
// if w/ brace right before }
fDocument.set("\tif (true) {\n" +
"\t\t}");
String indent= fScanner.computeIndentation(fDocument.getLength() - 1).toString();
Assert.assertEquals("\t", indent);
}
public void testIndentation21() {
// double if w/ brace
fDocument.set("\tif (true)\n" +
"\t\tif (true) {\n" +
"");
String indent= fScanner.computeIndentation(fDocument.getLength()).toString();
Assert.assertEquals("\t\t\t", indent);
}
public void testIndentation22() {
// after double if w/ brace
fDocument.set("\tif (true)\n" +
"\t\tif (true) {\n" +
"\t\t\tstuff();" +
"\t\t}\n" +
"");
String indent= fScanner.computeIndentation(fDocument.getLength()).toString();
Assert.assertEquals("\t", indent); // because of possible dangling else
}
public void testIndentation22a() {
// after double if w/ brace
fDocument.set("\tif (true)\n" +
"\t\tif (true) {\n" +
"\t\t\tstuff();\n" +
"\t\t}\n" +
"");
String indent= fScanner.computeIndentation(fDocument.getLength() - 2).toString();
Assert.assertEquals("\t\t", indent);
}
public void testIndentation22b() {
// after double if w/ brace
fDocument.set("\tif (true)\n" +
"\t\tif (true) {\n" +
"\t\t\tstuff();" +
"\t\t}\n" +
"a");
String indent= fScanner.computeIndentation(fDocument.getLength() - 1).toString();
Assert.assertEquals("\t", indent); // no dangling else possible
}
public void testIndentation23() {
// do
fDocument.set("\tdo\n" +
"");
String indent= fScanner.computeIndentation(fDocument.getLength()).toString();
Assert.assertEquals("\t\t", indent);
}
public void testIndentation24() {
// braceless else
fDocument.set("\tif (true) {\n" +
"\t\tstuff();\n" +
"\t} else\n" +
"\t\tnoStuff");
String indent= fScanner.computeIndentation(fDocument.getLength()).toString();
Assert.assertEquals("\t\t", indent);
}
public void testIndentation25() {
// braceless else
fDocument.set("\tif (true) {\r\n" +
"\t\tstuff();\r\n" +
"\t} else\r\n" +
"\t\tnoStuff;\r\n");
String indent= fScanner.computeIndentation(fDocument.getLength()).toString();
Assert.assertEquals("\t", indent);
}
public void testIndentation26() {
// do while
fDocument.set("\tdo\n" +
"\t\t\n" +
"\twhile (true);" +
"");
String indent= fScanner.computeIndentation(fDocument.getLength()).toString();
Assert.assertEquals("\t", indent);
}
public void testIndentation27() {
// do while
fDocument.set("\tdo\n" +
"\t\t;\n" +
"\twhile (true);" +
"");
int i= fScanner.findReferencePosition(8);
Assert.assertEquals(1, i);
String indent= fScanner.computeIndentation(8).toString();
Assert.assertEquals("\t", indent);
}
public void testIndentation28() {
// TODO do while - how to we distinguish from while {} loop?
fDocument.set("\tdo\n" +
"\t\t;\n" +
"\twhile (true);" +
"");
int i= fScanner.findReferencePosition(fDocument.getLength());
Assert.assertEquals(1, i);
String indent= fScanner.computeIndentation(fDocument.getLength()).toString();
Assert.assertEquals("\t", indent);
}
public void testIndentation29() {
fDocument.set("\t\twhile (condition)\n" +
"\t\t\twhile (condition)\n" +
"\t\t\t\tfoo();\n");
int i= fScanner.findReferencePosition(fDocument.getLength());
Assert.assertEquals(2, i);
String indent= fScanner.computeIndentation(fDocument.getLength()).toString();
Assert.assertEquals("\t\t", indent);
}
public void testIndentation30() {
// braceless else
fDocument.set("\tif (true)\n" +
"\t{");
String indent= fScanner.computeIndentation(fDocument.getLength() - 1).toString();
Assert.assertEquals("\t", indent);
}
public void testIndentation31() {
// braceless else
fDocument.set("\tif (true)\n" +
"{\t\n" +
"\t\tstuff();\n" +
"\t} else\n" +
"\t\tnoStuff");
String indent= fScanner.computeIndentation(fDocument.getLength()).toString();
Assert.assertEquals("\t\t", indent);
}
public void testIndentation32() {
// braceless else
fDocument.set("\tswitch(ch) {\n" +
"\t\tcase one:\n");
String indent= fScanner.computeIndentation(fDocument.getLength()).toString();
Assert.assertEquals(" ", indent);
}
public void testAnonymousIndentation1() {
fDocument.set( " MenuItem mi= new MenuItem(\"About...\");\n" +
" mi->addActionListener(\n" +
" new ActionListener() {\n"
);
String indent= fScanner.computeIndentation(fDocument.getLength()).toString();
Assert.assertEquals(" ", indent);
}
public void testAnonymousIndentation2() {
fDocument.set( " MenuItem mi= new MenuItem(\"About...\");\n" +
" mi->addActionListener(\n" +
" new ActionListener() {\n" +
" public void actionPerformed(ActionEvent event) {\n" +
" about();\n" +
" }\n" +
" }\n" +
");"
);
// this is bogus, since this is really just an unfinished call argument list - how could we know
String indent= fScanner.computeIndentation(fDocument.getLength() - 2).toString();
Assert.assertEquals(" ", indent);
}
public void testExceptionIndentation1() {
fDocument.set("public void processChildren(CompositeExpression result, IConfigurationElement element) throws CoreException {\n" +
" IConfigurationElement[] children= element.getChildren();\n" +
" if (children != null) {\n" +
" for (int i= 0; i < children.length; i++) {\n" +
" Expression child= parse(children[i]);\n" +
" if (child == null)\n" +
" new Bla(new CoreExeption(new Status(IStatus.ERROR, JavaPlugin.getPluginId()");
String indent= fScanner.computeIndentation(fDocument.getLength()).toString();
Assert.assertEquals(" ", indent);
}
public void testExceptionIndentation2() {
fDocument.set("public void processChildren(CompositeExpression result, IConfigurationElement element) throws CoreException {\n" +
" IConfigurationElement[] children= element.getChildren();\n" +
" if (children != null) {\n" +
" for (int i= 0; i < children.length; i++) {\n" +
" Expression child= parse(children[i]);\n" +
" if (child == null)\n" +
" new Bla(new CoreExeption(new Status(IStatus.ERROR, JavaPlugin.getPluginId(),");
String indent= fScanner.computeIndentation(fDocument.getLength()).toString();
Assert.assertEquals(" ", indent);
}
public void testExceptionIndentation3() {
fDocument.set("public void processChildren(CompositeExpression result, IConfigurationElement element) throws CoreException {\n" +
" IConfigurationElement[] children= element.getChildren();\n" +
" if (children != null) {\n" +
" for (int i= 0; i < children.length; i++) {\n" +
" Expression child= parse(children[i]);\n" +
" if (child == null)\n" +
" new char[] { new CoreExeption(new Status(IStatus.ERROR, JavaPlugin.getPluginId(),");
String indent= fScanner.computeIndentation(fDocument.getLength()).toString();
Assert.assertEquals(" ", indent);
}
public void testListAlignmentMethodDeclaration() {
// parameter declaration - alignment with parenthesis
fDocument.set( "\tvoid proc ( int par1, int par2,\n" +
" int par3, int par4,\n");
String indent= fScanner.computeIndentation(fDocument.getLength()).toString();
Assert.assertEquals(" ", indent);
}
public void testListAlignmentMethodCall() {
// parameter declaration - alignment with parenthesis
fDocument.set( "\this->proc (par1, par2,\n" +
" par3, par4,\n");
String indent= fScanner.computeIndentation(fDocument.getLength()).toString();
Assert.assertEquals(" ", indent);
}
public void testListAlignmentArray() {
// parameter declaration - alignment with parenthesis
fDocument.set( "\tint[]= new int[] { 1, two,\n" +
" three, four,\n");
String indent= fScanner.computeIndentation(fDocument.getLength()).toString();
Assert.assertEquals(" ", indent);
}
public void testListAlignmentArray2() {
// no prior art - probe system settings.
fDocument.set( "\tint[]= new int[] { 1, two,\n");
String indent= fScanner.computeIndentation(fDocument.getLength()).toString();
Assert.assertEquals("\t ", indent);
}
public void testBraceAlignmentOfMultilineDeclaration() {
fDocument.set( " int foobar(int one, int two,\n" +
" int three, int four,\n" +
" int five) {\n" +
" \n" +
" return 0;\n" +
" }");
String indent= fScanner.computeIndentation(fDocument.getLength() - 1).toString();
Assert.assertEquals(" ", indent);
}
public void testBlocksInCaseStatements() {
fDocument.set(
" switch (i) {\n" +
" case 1:\n" +
" new Runnable() {\n" +
"");
String indent= fScanner.computeIndentation(fDocument.getLength()).toString();
Assert.assertEquals(" ", indent);
}
public void testAnonymousTypeBraceNextLine() throws Exception {
fDocument.set(
" MenuItem mi= new MenuItem(\"About...\");\n" +
" mi->addActionListener(new ActionListener() " +
" {\n"
);
String indent= fScanner.computeIndentation(fDocument.getLength() - 2).toString();
Assert.assertEquals(" ", indent);
}
public void testClassInstanceCreationHeuristic() throws Exception {
fDocument.set(" method(new std::vector<std::string>(10), foo, new int[])");
for (int offset= 0; offset < 15; offset++)
assertFalse(fHeuristicScanner.looksLikeClassInstanceCreationBackward(offset, CHeuristicScanner.UNBOUND));
for (int offset= 15; offset < 18; offset++)
assertTrue(fHeuristicScanner.looksLikeClassInstanceCreationBackward(offset, CHeuristicScanner.UNBOUND));
for (int offset= 18; offset < 20; offset++)
assertFalse(fHeuristicScanner.looksLikeClassInstanceCreationBackward(offset, CHeuristicScanner.UNBOUND));
for (int offset= 20; offset < 26; offset++)
assertTrue(fHeuristicScanner.looksLikeClassInstanceCreationBackward(offset, CHeuristicScanner.UNBOUND));
for (int offset= 26; offset < 48; offset++)
assertFalse(fHeuristicScanner.looksLikeClassInstanceCreationBackward(offset, CHeuristicScanner.UNBOUND));
for (int offset= 48; offset < 54; offset++)
assertFalse(fHeuristicScanner.looksLikeClassInstanceCreationBackward(offset, CHeuristicScanner.UNBOUND));
for (int offset= 54; offset < 57; offset++)
assertTrue(fHeuristicScanner.looksLikeClassInstanceCreationBackward(offset, CHeuristicScanner.UNBOUND));
for (int offset= 57; offset < 59; offset++)
assertFalse(fHeuristicScanner.looksLikeClassInstanceCreationBackward(offset, CHeuristicScanner.UNBOUND));
}
public void testShiftOperator() throws Exception {
fDocument.set(
" for (int j = 0; j == 0; j ++) {\n" +
" j = 3 >> 1;\n"
);
String indent= fScanner.computeIndentation(fDocument.getLength()).toString();
Assert.assertEquals("\t\t\t", indent);
}
public void testConditional1() throws Exception {
if (true) // XXX enable when https://bugs.eclipse.org/bugs/show_bug.cgi?id=65463 is fixed
return;
fDocument.set(
" boolean isPrime() {\n" +
" return fPrime == true ? true\n" +
" : false;"
);
String indent= fScanner.computeIndentation(fDocument.getLength() - 8).toString();
Assert.assertEquals(" ", indent);
}
public void testConditional2() throws Exception {
if (true) // XXX enable when https://bugs.eclipse.org/bugs/show_bug.cgi?id=65463 is fixed
return;
fDocument.set(
" boolean isPrime() {\n" +
" return fPrime == true" +
" ? true\n" +
" : false;"
);
String indent= fScanner.computeIndentation(fDocument.getLength() - 8).toString();
Assert.assertEquals(" ", indent);
}
}

View file

@ -12,8 +12,10 @@
package org.eclipse.cdt.ui.tests.text;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
@ -446,6 +448,18 @@ public class EditorTestHelper {
return cProject;
}
public static IFile createFile(IContainer container, String fileName, String contents, IProgressMonitor monitor) throws CoreException {
//Obtain file handle
IFile file = container.getFile(new Path(fileName));
InputStream stream = new ByteArrayInputStream(contents.getBytes());
//Create file input stream
if(file.exists())
file.setContents(stream, false, false, monitor);
else
file.create(stream, false, monitor);
return file;
}
public static IFile[] findFiles(IResource resource) throws CoreException {
List files= new ArrayList();
findFiles(resource, files);

View file

@ -0,0 +1,127 @@
/*******************************************************************************
* Copyright (c) 2005, 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
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
* Anton Leherbauer (Wind River Systems)
*******************************************************************************/
package org.eclipse.cdt.ui.tests.text;
import java.util.ListResourceBundle;
import junit.extensions.TestSetup;
import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.source.SourceViewer;
import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.formatter.DefaultCodeFormatterConstants;
import org.eclipse.cdt.core.model.ICProject;
import org.eclipse.cdt.core.testplugin.CProjectHelper;
import org.eclipse.cdt.internal.ui.actions.IndentAction;
import org.eclipse.cdt.internal.ui.editor.CEditor;
/**
* Test the IndentAction.
*/
public class IndentActionTest extends TestCase {
private static final String PROJECT= "IndentTests";
private static final class EmptyBundle extends ListResourceBundle {
protected Object[][] getContents() {
return new Object[0][];
}
}
protected static class IndentTestSetup extends TestSetup {
private ICProject fCProject;
public IndentTestSetup(Test test) {
super(test);
}
protected void setUp() throws Exception {
super.setUp();
fCProject= EditorTestHelper.createCProject(PROJECT, "resources/indentation");
fCProject.setOption(DefaultCodeFormatterConstants.FORMATTER_TAB_CHAR, CCorePlugin.TAB);
}
protected void tearDown () throws Exception {
if (fCProject != null)
CProjectHelper.delete(fCProject);
super.tearDown();
}
}
private static final Class THIS= IndentActionTest.class;
public static Test suite() {
return new IndentTestSetup(new TestSuite(THIS));
}
private CEditor fEditor;
private SourceViewer fSourceViewer;
private IDocument fDocument;
/*
* @see junit.framework.TestCase#setUp()
*/
protected void setUp() throws Exception {
String filename= createFileName("Before");
fEditor= (CEditor) EditorTestHelper.openInEditor(ResourceTestHelper.findFile(filename), true);
fSourceViewer= EditorTestHelper.getSourceViewer(fEditor);
fDocument= fSourceViewer.getDocument();
}
/*
* @see junit.framework.TestCase#tearDown()
*/
protected void tearDown() throws Exception {
EditorTestHelper.closeEditor(fEditor);
}
private void assertIndentResult() throws Exception {
String afterFile= createFileName("After");
String expected= ResourceTestHelper.read(afterFile).toString();
new IndentAction(new EmptyBundle(), "prefix", fEditor, false).run();
assertEquals(expected, fDocument.get());
}
private String createFileName(String qualifier) {
String name= getName();
name= name.substring(4, 5).toLowerCase() + name.substring(5);
return "/" + PROJECT + "/src/" + name + "/" + qualifier + ".cpp";
}
private void selectAll() {
fSourceViewer.setSelectedRange(0, fDocument.getLength());
}
public void testUnchanged() throws Exception {
selectAll();
assertIndentResult();
}
public void testSample() throws Exception {
selectAll();
assertIndentResult();
}
public void testComplex() throws Exception {
selectAll();
assertIndentResult();
}
}

View file

@ -21,12 +21,16 @@ public class TextTestSuite extends TestSuite {
public TextTestSuite() {
super("Tests in package org.eclipse.cdt.ui.tests.text");
// partitioning tests
addTest(PartitionTokenScannerTest.suite());
addTest(NumberRuleTest.suite());
addTest(CAutoIndentTest.suite());
addTest(CPartitionerTest.suite());
addTest(PairMatcherTest.suite());
// smart edit tests
addTest(CAutoIndentTest.suite());
addTest(CHeuristicScannerTest.suite());
addTest(BracketInserterTest.suite());
addTest(IndentActionTest.suite());
// Break iterator tests.
addTest(CBreakIteratorTest.suite());
@ -36,6 +40,8 @@ public class TextTestSuite extends TestSuite {
addTest(SemanticHighlightingTest.suite());
addTest(InactiveCodeHighlightingTest.suite());
addTest(CHeaderRuleTest.suite());
addTest(NumberRuleTest.suite());
addTest(PairMatcherTest.suite());
// folding tests
addTest(FoldingTest.suite());

View file

@ -8,6 +8,7 @@
* Contributors:
* IBM Corporation - initial API and implementation
* Sergey Prigogin, Google
* Anton Leherbauer (Wind River Systems)
*******************************************************************************/
package org.eclipse.cdt.internal.ui.actions;
@ -188,13 +189,13 @@ public class IndentAction extends TextEditorAction {
}
/**
* Indents a single line using the java heuristic scanner. Cdoc and multiline comments are
* Indents a single line using the heuristic scanner. Cdoc and multiline comments are
* indented as specified by the <code>CDocAutoIndentStrategy</code>.
*
* @param document the document
* @param line the line to be indented
* @param caret the caret position
* @param indenter the java indenter
* @param indenter the indenter
* @param scanner the heuristic scanner
* @param multiLine <code>true</code> if more than one line is being indented
* @return <code>true</code> if <code>document</code> was modified, <code>false</code> otherwise
@ -211,7 +212,9 @@ public class IndentAction extends TextEditorAction {
ITypedRegion startingPartition= TextUtilities.getPartition(document, ICPartitions.C_PARTITIONING, offset, false);
String type= partition.getType();
if (type.equals(ICPartitions.C_MULTI_LINE_COMMENT)) {
indent= computeDocIndent(document, line, scanner, startingPartition);
indent= computeCommentIndent(document, line, scanner, startingPartition);
} else if (startingPartition.getType().equals(ICPartitions.C_PREPROCESSOR)) {
indent= computePreprocessorIndent(document, line, scanner, startingPartition);
} else if (!fIsTabAction && startingPartition.getOffset() == offset && startingPartition.getType().equals(ICPartitions.C_SINGLE_LINE_COMMENT)) {
// line comment starting at position 0 -> indent inside
int max= document.getLength() - offset;
@ -245,7 +248,7 @@ public class IndentAction extends TextEditorAction {
}
}
// standard java indentation
// standard C indentation
if (indent == null) {
StringBuffer computed= indenter.computeIndentation(offset);
if (computed != null)
@ -292,18 +295,17 @@ public class IndentAction extends TextEditorAction {
}
/**
* Computes and returns the indentation for a javadoc line. The line
* must be inside a javadoc comment.
* Computes and returns the indentation for a comment line.
*
* @param document the document
* @param line the line in document
* @param scanner the scanner
* @param partition the javadoc partition
* @param partition the comment partition
* @return the indent, or <code>null</code> if not computable
* @throws BadLocationException
*/
private String computeDocIndent(IDocument document, int line, CHeuristicScanner scanner, ITypedRegion partition) throws BadLocationException {
if (line == 0) // impossible - the first line is never inside a javadoc comment
private String computeCommentIndent(IDocument document, int line, CHeuristicScanner scanner, ITypedRegion partition) throws BadLocationException {
if (line == 0) // impossible - the first line is never inside a comment comment
return null;
// don't make any assumptions if the line does not start with \s*\* - it might be
@ -347,6 +349,20 @@ public class IndentAction extends TextEditorAction {
return buf.toString();
}
/**
* Computes and returns the indentation for a preprocessor line.
*
* @param document the document
* @param line the line in document
* @param scanner the scanner
* @param partition the comment partition
* @return the indent, or <code>null</code> if not computable
* @throws BadLocationException
*/
private String computePreprocessorIndent(IDocument document, int line, CHeuristicScanner scanner, ITypedRegion partition) throws BadLocationException {
return ""; //$NON-NLS-1$
}
/**
* Returns the size in characters of a string. All characters count one, tabs count the editor's
* preference for the tab display
@ -390,7 +406,7 @@ public class IndentAction extends TextEditorAction {
}
/**
* Returns the tab size used by the java editor, which is deduced from the
* Returns the tab size used by the editor, which is deduced from the
* formatter preferences.
*
* @return the tab size as defined in the current formatter preferences

View file

@ -692,7 +692,8 @@ public class CEditor extends TextEditor implements ISelectionChangedListener, IR
}
ITypedRegion partition = TextUtilities.getPartition(document, ICPartitions.C_PARTITIONING, offset, true);
if (!IDocument.DEFAULT_CONTENT_TYPE.equals(partition.getType()))
if (!IDocument.DEFAULT_CONTENT_TYPE.equals(partition.getType())
&& !ICPartitions.C_PREPROCESSOR.equals(partition.getType()))
return;
if (!validateEditorInputState())

View file

@ -7,6 +7,8 @@
*
* Contributors:
* IBM Corporation - initial API and implementation
* Sergey Prigogin, Google
* Anton Leherbauer (Wind River Systems)
*******************************************************************************/
package org.eclipse.cdt.internal.ui.text;
@ -88,7 +90,7 @@ public final class CHeuristicScanner implements Symbols {
*/
private static class NonWhitespace extends StopCondition {
/*
* @see org.eclipse.jdt.internal.ui.text.JavaHeuristicScanner.StopCondition#stop(char)
* @see org.eclipse.cdt.internal.ui.text.CHeuristicScanner.StopCondition#stop(char)
*/
public boolean stop(char ch, int position, boolean forward) {
return !Character.isWhitespace(ch);
@ -102,14 +104,14 @@ public final class CHeuristicScanner implements Symbols {
*/
private final class NonWhitespaceDefaultPartition extends NonWhitespace {
/*
* @see org.eclipse.jdt.internal.ui.text.JavaHeuristicScanner.StopCondition#stop(char)
* @see org.eclipse.cdt.internal.ui.text.CHeuristicScanner.StopCondition#stop(char)
*/
public boolean stop(char ch, int position, boolean forward) {
return super.stop(ch, position, true) && isDefaultPartition(position);
}
/*
* @see org.eclipse.jdt.internal.ui.text.JavaHeuristicScanner.StopCondition#nextPosition(int, boolean)
* @see org.eclipse.cdt.internal.ui.text.CHeuristicScanner.StopCondition#nextPosition(int, boolean)
*/
public int nextPosition(int position, boolean forward) {
ITypedRegion partition= getPartition(position);
@ -134,7 +136,7 @@ public final class CHeuristicScanner implements Symbols {
*/
private static class NonJavaIdentifierPart extends StopCondition {
/*
* @see org.eclipse.jdt.internal.ui.text.JavaHeuristicScanner.StopCondition#stop(char)
* @see org.eclipse.cdt.internal.ui.text.CHeuristicScanner.StopCondition#stop(char)
*/
public boolean stop(char ch, int position, boolean forward) {
return !Character.isJavaIdentifierPart(ch);
@ -148,14 +150,14 @@ public final class CHeuristicScanner implements Symbols {
*/
private final class NonJavaIdentifierPartDefaultPartition extends NonJavaIdentifierPart {
/*
* @see org.eclipse.jdt.internal.ui.text.JavaHeuristicScanner.StopCondition#stop(char)
* @see org.eclipse.cdt.internal.ui.text.CHeuristicScanner.StopCondition#stop(char)
*/
public boolean stop(char ch, int position, boolean forward) {
return super.stop(ch, position, true) || !isDefaultPartition(position);
}
/*
* @see org.eclipse.jdt.internal.ui.text.JavaHeuristicScanner.StopCondition#nextPosition(int, boolean)
* @see org.eclipse.cdt.internal.ui.text.CHeuristicScanner.StopCondition#nextPosition(int, boolean)
*/
public int nextPosition(int position, boolean forward) {
ITypedRegion partition= getPartition(position);
@ -201,14 +203,14 @@ public final class CHeuristicScanner implements Symbols {
}
/*
* @see org.eclipse.jdt.internal.ui.text.JavaHeuristicScanner.StopCondition#stop(char, int)
* @see org.eclipse.cdt.internal.ui.text.CHeuristicScanner.StopCondition#stop(char, int)
*/
public boolean stop(char ch, int position, boolean forward) {
return Arrays.binarySearch(fChars, ch) >= 0 && isDefaultPartition(position);
}
/*
* @see org.eclipse.jdt.internal.ui.text.JavaHeuristicScanner.StopCondition#nextPosition(int, boolean)
* @see org.eclipse.cdt.internal.ui.text.CHeuristicScanner.StopCondition#nextPosition(int, boolean)
*/
public int nextPosition(int position, boolean forward) {
ITypedRegion partition= getPartition(position);
@ -268,7 +270,7 @@ public final class CHeuristicScanner implements Symbols {
}
/**
* Calls <code>this(document, ICPartitions.JAVA_PARTITIONING, IDocument.DEFAULT_CONTENT_TYPE)</code>.
* Calls <code>this(document, ICPartitions.C_PARTITIONING, IDocument.DEFAULT_CONTENT_TYPE)</code>.
*
* @param document the document to scan.
*/
@ -841,18 +843,18 @@ public final class CHeuristicScanner implements Symbols {
* <code>true</code> if <code>start</code> is at the following positions (|):
*
* <pre>
* new java.util. ArrayList|&lt;String&gt;(10)
* new ArrayList |(10)
* new / * comment * / ArrayList |(10)
* new new std::vector&lt;std::string&gt;|(10)
* new new str_vector |(10)
* new new / * comment * / str_vector |(10)
* </pre>
*
* but not the following:
*
* <pre>
* new java.util. ArrayList&lt;String&gt;(10)|
* new java.util. ArrayList&lt;String&gt;|(10)
* new ArrayList (10)|
* ArrayList |(10)
* new new std::vector&lt;std::string&gt;(10)|
* new new std::vector&lt;std::string&gt;|(10)
* new new vector (10)|
* vector |(10)
* </pre>
*
* @param start the position where the type name of the class instance creation supposedly ends
@ -865,7 +867,10 @@ public final class CHeuristicScanner implements Symbols {
int token= previousToken(start - 1, bound);
if (token == Symbols.TokenIDENT) { // type name
token= previousToken(getPosition(), bound);
while (token == Symbols.TokenOTHER) { // dot of qualification
while (token == Symbols.TokenCOLON) { // colon of qualification
token= previousToken(getPosition(), bound);
if (token != Symbols.TokenCOLON) // second colon of qualification
return false;
token= previousToken(getPosition(), bound);
if (token != Symbols.TokenIDENT) // qualification name
return false;

View file

@ -8,6 +8,7 @@
* Contributors:
* IBM Corporation - initial API and implementation
* Sergey Prigogin, Google
* Anton Leherbauer (Wind River Systems)
*******************************************************************************/
package org.eclipse.cdt.internal.ui.text;
@ -1582,6 +1583,25 @@ public final class CIndenter {
return false;
}
/**
* Skips scope qualifiers of identifiers.
*
* @return <code>true</code> if a qualifier was encountered, the last token
* will be an IDENT.
*/
private boolean skipQualifiers() {
if (fToken == Symbols.TokenCOLON) {
nextToken();
if (fToken == Symbols.TokenCOLON) {
nextToken();
if (fToken == Symbols.TokenIDENT) {
return true;
}
}
}
return false;
}
/**
* Reads the next token in backward direction from the heuristic scanner
* and sets the fields <code>fToken, fPreviousPosition</code> and <code>fPosition</code>
@ -1621,17 +1641,10 @@ public final class CIndenter {
* declaration header.
*/
private boolean looksLikeMethodDecl() {
/*
* TODO This heuristic does not recognize package private constructors
* since those do have neither type nor visibility keywords.
* One option would be to go over the parameter list, but that might
* be empty as well, or not typed in yet - hard to do without an AST...
*/
nextToken();
if (fToken == Symbols.TokenIDENT) { // method name
do nextToken();
while (skipBrackets()); // optional brackets for array valued return types
while (skipBrackets() || skipQualifiers()); // optional brackets for array valued return types
return fToken == Symbols.TokenIDENT; // return type name
@ -1674,7 +1687,7 @@ public final class CIndenter {
* header.
*/
private boolean looksLikeMethodCall() {
// TODO add awareness for constructor calls with generic types: new ArrayList<String>()
// TODO add awareness for constructor calls with templates: new complex<float>()
nextToken();
return fToken == Symbols.TokenIDENT; // method name
}

View file

@ -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
@ -7,6 +7,7 @@
*
* Contributors:
* IBM Corporation - initial API and implementation
* Sergey Prigogin, Google
*******************************************************************************/
package org.eclipse.cdt.internal.ui.text;
@ -43,11 +44,11 @@ public interface Symbols {
int TokenSWITCH= 1020;
int TokenGOTO= 1021;
int TokenDEFAULT= 1022;
int TokenPRIVATE= 1023;
int TokenPROTECTED= 1024;
int TokenPUBLIC= 1025;
int TokenPRIVATE= 1023;
int TokenPROTECTED= 1024;
int TokenPUBLIC= 1025;
int TokenNEW= 1026;
int TokenDELETE= 1027;
int TokenDELETE= 1027;
int TokenCLASS= 1028;
int TokenSTRUCT= 1029;
int TokenENUM= 1030;