|
From: <caw...@us...> - 2007-08-22 16:40:11
|
Revision: 3045
http://rubyeclipse.svn.sourceforge.net/rubyeclipse/?rev=3045&view=rev
Author: cawilliams
Date: 2007-08-22 09:40:08 -0700 (Wed, 22 Aug 2007)
Log Message:
-----------
start work on an AST based code formatter...
Modified Paths:
--------------
trunk/org.rubypeople.rdt.core.tests/src/org/rubypeople/rdt/internal/formatter/FormatTestData.xml
trunk/org.rubypeople.rdt.core.tests/src/org/rubypeople/rdt/internal/formatter/TC_CodeFormatter.java
Added Paths:
-----------
trunk/org.rubypeople.rdt.core.tests/src/org/rubypeople/rdt/internal/formatter/TC_ASTBasedCodeFormatter.java
trunk/org.rubypeople.rdt.core.tests/src/org/rubypeople/rdt/internal/formatter/TC_ASTBasedCodeFormatter_Data.xml
Modified: trunk/org.rubypeople.rdt.core.tests/src/org/rubypeople/rdt/internal/formatter/FormatTestData.xml
===================================================================
--- trunk/org.rubypeople.rdt.core.tests/src/org/rubypeople/rdt/internal/formatter/FormatTestData.xml 2007-08-22 16:39:58 UTC (rev 3044)
+++ trunk/org.rubypeople.rdt.core.tests/src/org/rubypeople/rdt/internal/formatter/FormatTestData.xml 2007-08-22 16:40:08 UTC (rev 3045)
@@ -5,7 +5,7 @@
<part>
<assertionMessage>Keywords</assertionMessage>
<unformatted>
-class xx
+class Xx
def xx()
if bla() then
bla
@@ -16,7 +16,7 @@
end
</unformatted>
<formatted>
-class xx
+class Xx
def xx()
if bla() then
bla
Added: trunk/org.rubypeople.rdt.core.tests/src/org/rubypeople/rdt/internal/formatter/TC_ASTBasedCodeFormatter.java
===================================================================
--- trunk/org.rubypeople.rdt.core.tests/src/org/rubypeople/rdt/internal/formatter/TC_ASTBasedCodeFormatter.java (rev 0)
+++ trunk/org.rubypeople.rdt.core.tests/src/org/rubypeople/rdt/internal/formatter/TC_ASTBasedCodeFormatter.java 2007-08-22 16:40:08 UTC (rev 3045)
@@ -0,0 +1,27 @@
+package org.rubypeople.rdt.internal.formatter;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+import javax.xml.parsers.FactoryConfigurationError;
+import javax.xml.parsers.ParserConfigurationException;
+
+import org.rubypeople.rdt.core.formatter.CodeFormatter;
+import org.xml.sax.SAXException;
+
+public class TC_ASTBasedCodeFormatter extends TC_CodeFormatter {
+
+ public TC_ASTBasedCodeFormatter(String name) throws SAXException, IOException, ParserConfigurationException, FactoryConfigurationError {
+ super(name);
+ }
+
+ @Override
+ protected CodeFormatter getCodeFormatter() {
+ return new ASTBasedCodeFormatter();
+ }
+
+ protected InputStream getInputDataStream() {
+ return this.getClass().getResourceAsStream("TC_ASTBasedCodeFormatter_Data.xml");
+ }
+
+}
Property changes on: trunk/org.rubypeople.rdt.core.tests/src/org/rubypeople/rdt/internal/formatter/TC_ASTBasedCodeFormatter.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Added: trunk/org.rubypeople.rdt.core.tests/src/org/rubypeople/rdt/internal/formatter/TC_ASTBasedCodeFormatter_Data.xml
===================================================================
--- trunk/org.rubypeople.rdt.core.tests/src/org/rubypeople/rdt/internal/formatter/TC_ASTBasedCodeFormatter_Data.xml (rev 0)
+++ trunk/org.rubypeople.rdt.core.tests/src/org/rubypeople/rdt/internal/formatter/TC_ASTBasedCodeFormatter_Data.xml 2007-08-22 16:40:08 UTC (rev 3045)
@@ -0,0 +1,722 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<tests>
+ <test ID="Keywords">
+
+<part>
+<assertionMessage>Keywords</assertionMessage>
+<unformatted>
+class Xx
+ def xx()
+ if bla() then
+bla
+ else
+ arg
+ end
+end
+end
+</unformatted>
+<formatted>
+class Xx
+ def xx()
+ if bla() then
+ bla
+ else
+ arg
+ end
+ end
+end
+</formatted>
+</part>
+
+<part>
+<assertionMessage>Keyword with following delimiter</assertionMessage>
+<unformatted>
+if(true)
+while(true)do
+if/test/=~"test" then
+puts "TEST MATCHES" ;
+elsif/test/=~"abc"
+puts "ABC MATCHES";
+end
+end
+end
+</unformatted>
+<formatted>
+if(true)
+ while(true)do
+ if/test/=~"test" then
+ puts "TEST MATCHES" ;
+ elsif/test/=~"abc"
+ puts "ABC MATCHES";
+ end
+ end
+end
+</formatted>
+</part>
+
+
+<part>
+<assertionMessage>Keyword in comment</assertionMessage>
+<unformatted>
+# class
+class abc
+end
+</unformatted>
+<formatted>
+# class
+class abc
+end
+</formatted>
+</part>
+
+<part>
+<assertionMessage>Keyword as method name</assertionMessage>
+<unformatted>
+object.class
+puts o
+</unformatted>
+<formatted>
+object.class
+puts o
+</formatted>
+</part>
+
+ </test>
+
+ <test ID="takeIndentationOfFirstKeyword">
+<unformatted>
+ # comment
+ def firstMethod
+ if a
+ b
+ end
+ end
+</unformatted>
+<formatted>
+ # comment
+ def firstMethod
+ if a
+ b
+ end
+ end
+</formatted>
+ </test>
+
+<test ID="blockWithBrackets">
+<part>
+<assertionMessage>Block starts in middle of line</assertionMessage>
+<unformatted>
+a.each { | x |
+if a
+b
+end
+}
+</unformatted>
+<formatted>
+a.each { | x |
+ if a
+ b
+ end
+}
+</formatted>
+</part>
+<part>
+<assertionMessage>Block starts in new line</assertionMessage>
+<unformatted>
+a.each
+{ | x |
+test
+}
+</unformatted>
+<formatted>
+a.each
+{ | x |
+ test
+}
+</formatted>
+</part>
+</test>
+
+
+<test ID="Blocks">
+<part>
+<assertionMessage>Begin/rescue/end block</assertionMessage>
+<unformatted>
+begin
+ x
+rescue
+ y
+end
+</unformatted>
+<formatted>
+begin
+ x
+rescue
+ y
+end
+</formatted>
+</part>
+<part>
+<assertionMessage>Begin/rescue/end in one line</assertionMessage>
+<unformatted>
+begin a rescue x end
+</unformatted>
+<formatted>
+begin a rescue x end
+</formatted>
+</part>
+
+<part>
+<assertionMessage>No-Block Do</assertionMessage>
+<unformatted>
+while (a) do
+test
+end
+x = 5 ; until x do
+test
+end
+</unformatted>
+<formatted>
+while (a) do
+ test
+end
+x = 5 ; until x do
+ test
+end
+</formatted>
+</part>
+
+<part>
+<assertionMessage>Block Do</assertionMessage>
+<unformatted>
+3.timeswhile do
+test
+end
+while (a) x end ; 2.times do
+test
+end
+</unformatted>
+<formatted>
+3.timeswhile do
+ test
+end
+while (a) x end ; 2.times do
+ test
+end
+</formatted>
+</part>
+
+<part>
+<assertionMessage>No Block Expressions</assertionMessage>
+<unformatted>
+a = 0 if a != 0
+test
+a() if trace?
+a +=1 while a != 10
+i += 1 until i == 5
+test
+</unformatted>
+<formatted>
+a = 0 if a != 0
+test
+a() if trace?
+a +=1 while a != 10
+i += 1 until i == 5
+test
+</formatted>
+</part>
+
+<part>
+<assertionMessage>Block Expressions starting in the middle of a line</assertionMessage>
+<unformatted>
+a = 0 ; if a != 0
+test
+end
+a = if a != 0
+5
+end
+</unformatted>
+<formatted>
+a = 0 ; if a != 0
+ test
+end
+a = if a != 0
+ 5
+end
+</formatted>
+</part>
+
+<part>
+<assertionMessage>Until with Begin/End</assertionMessage>
+<unformatted>
+begin
+i+=1
+end until i == 5
+test
+</unformatted>
+<formatted>
+begin
+ i+=1
+end until i == 5
+test
+</formatted>
+</part>
+
+<part>
+<assertionMessage>End with following semicolon</assertionMessage>
+<unformatted>
+class A
+end;
+</unformatted>
+<formatted>
+class A
+end;
+</formatted>
+</part>
+
+<part>
+<assertionMessage>Two ends in a row</assertionMessage>
+<unformatted>
+class A
+def a
+end;end
+class B end;
+</unformatted>
+<formatted>
+class A
+ def a
+ end;end
+class B end;
+</formatted>
+</part>
+
+<part>
+<assertionMessage>Semicolon before start</assertionMessage>
+<unformatted>
+def a;if 0 then puts "X"
+end;
+end;
+</unformatted>
+<formatted>
+def a;if 0 then puts "X"
+ end;
+end;
+</formatted>
+</part>
+</test>
+
+
+
+<test ID="Parameters">
+<part>
+<assertionMessage>Method Parameter in one line</assertionMessage>
+<unformatted>
+def x(a, b)
+y
+end
+</unformatted>
+<formatted>
+def x(a, b)
+ y
+end
+</formatted>
+</part>
+<part>
+<assertionMessage>Method Parameter in multiple lines</assertionMessage>
+<unformatted>
+
+def x(a
+b,
+ c)
+x
+end
+</unformatted>
+<formatted>
+
+def x(a
+ b,
+ c)
+ x
+end
+</formatted>
+</part>
+<part>
+<assertionMessage>Method call with multiple lines</assertionMessage>
+<unformatted>
+def x(a,b)
+object.method(arg1,
+ arg2)
+end
+</unformatted>
+<formatted>
+def x(a,b)
+ object.method(arg1,
+ arg2)
+end
+</formatted>
+</part>
+
+</test>
+
+<test ID="Literals">
+<part>
+<assertionMessage>Literal with double quotation</assertionMessage>
+<unformatted>
+ puts "def x(a, b)"
+ puts ""
+ if a
+b
+ end
+ puts "if{"
+ b
+ puts "end"
+</unformatted>
+<formatted>
+puts "def x(a, b)"
+puts ""
+if a
+ b
+end
+puts "if{"
+b
+puts "end"
+</formatted>
+</part>
+
+<part>
+<assertionMessage>Literal with double quotation over multiple lines</assertionMessage>
+<unformatted>
+ puts "Bla
+class"
+ puts "def method"
+ puts "end"
+</unformatted>
+<formatted>
+ puts "Bla
+class"
+ puts "def method"
+ puts "end"
+</formatted>
+</part>
+
+<part>
+<assertionMessage>Literal with backslashed quotation</assertionMessage>
+<unformatted>
+ puts "\"{"
+ puts "xx"
+ puts "class \\"
+if
+b
+</unformatted>
+<formatted>
+ puts "\"{"
+ puts "xx"
+ puts "class \\"
+ if
+ b
+</formatted>
+</part>
+
+<part>
+<assertionMessage>Literal with single quotation</assertionMessage>
+<unformatted>
+ puts 'def x(a, b)'
+ puts 'if{'
+ puts 'end'
+</unformatted>
+<formatted>
+ puts 'def x(a, b)'
+ puts 'if{'
+ puts 'end'
+</formatted>
+</part>
+<part>
+
+<assertionMessage>Special char $'</assertionMessage>
+<unformatted>
+if $'
+o.m
+end
+</unformatted>
+<formatted>
+if $'
+ o.m
+end
+</formatted>
+</part>
+
+<part>
+<assertionMessage>Literal with single and double quotation</assertionMessage>
+<unformatted>
+ puts '"def" if x(a, b)'
+ puts 'if{'
+ puts 'end'
+</unformatted>
+<formatted>
+ puts '"def" if x(a, b)'
+ puts 'if{'
+ puts 'end'
+</formatted>
+</part>
+<part>
+<assertionMessage>=begin, =end</assertionMessage>
+<unformatted>
+=begin
+ if
+ b
+ end
+=end
+ if
+ b
+ end
+</unformatted>
+<formatted>
+=begin
+ if
+ b
+ end
+=end
+if
+ b
+end
+</formatted>
+</part>
+
+<part>
+<assertionMessage>String def with <<ID ID</assertionMessage>
+<unformatted>
+<<ID
+ do not touch this ID while processing
+ test
+ID
+<<-ID
+ do not touch this while processing
+ test
+ ID
+<<'ID'
+ do not touch this while processing
+ test
+ID
+<<ID
+ uups
+ no end ID
+</unformatted>
+<formatted>
+<<ID
+ do not touch this ID while processing
+ test
+ID
+<<-ID
+ do not touch this while processing
+ test
+ ID
+<<'ID'
+ do not touch this while processing
+ test
+ID
+<<ID
+ uups
+ no end ID
+</formatted>
+</part>
+
+
+<part>
+<assertionMessage>regular expressions</assertionMessage>
+<unformatted>
+v =~ / { \/ { \\/
+if
+o.m()
+end
+v =~ /{/
+o.m()
+</unformatted>
+<formatted>
+v =~ / { \/ { \\/
+if
+ o.m()
+end
+v =~ /{/
+o.m()
+</formatted>
+</part>
+
+<part>
+<assertionMessage>regular expressions with multiple lines</assertionMessage>
+<comment>
+while ruby allows regular expressions with multiple lines, the code formatter won't consider them.
+the reason is, that the simple code formatting parser cannot make a decision if a slash is for starting
+a regex or for a division
+</comment>
+<unformatted>
+if /abc
+/ =~ "\ndef" then
+puts 'matched def' ;
+end
+</unformatted>
+<formatted>
+if /abc
+ / =~ "\ndef" then
+ puts 'matched def' ;
+end
+</formatted>
+</part>
+
+
+<part>
+<assertionMessage>Two divisions</assertionMessage>
+<unformatted>
+def a
+if true
+1/2
+else
+1/4
+end
+end
+</unformatted>
+<formatted>
+def a
+ if true
+ 1/2
+ else
+ 1/4
+ end
+end
+</formatted>
+</part>
+
+
+
+</test>
+
+<test ID="LiteralsStartingWithPercentSign">
+<part>
+<assertionMessage>literals starting with %</assertionMessage>
+<unformatted>
+puts %-class-
+puts %Q(class (m) class)
+puts %Q{class {m} class}
+puts %Q{ def class #{class} { if } class}
+puts ""
+</unformatted>
+<formatted>
+puts %-class-
+puts %Q(class (m) class)
+puts %Q{class {m} class}
+puts %Q{ def class #{class} { if } class}
+puts ""
+</formatted>
+</part>
+</test>
+
+
+<test ID="NegativeIndentation">
+
+<part>
+<assertionMessage>Invalid ruby with too many end</assertionMessage>
+<unformatted>
+class Bob
+ def m
+ end
+ end
+</unformatted>
+<formatted>
+class Bob
+ def m
+ end
+end
+</formatted>
+</part>
+
+</test>
+<test ID="RescueModifier">
+<part>
+<assertionMessage>Rescue Modifier</assertionMessage>
+<unformatted>
+class A
+ var = do_something rescue nil
+foo
+end
+</unformatted>
+<formatted>
+class A
+ var = do_something rescue nil
+ foo
+end
+</formatted>
+</part>
+<part>
+<assertionMessage>Rescue Modifier With Previous Block</assertionMessage>
+<unformatted>
+class A
+ begin
+do_something
+ rescue
+yeah
+ end
+ var = do_something rescue nil
+foo
+end
+</unformatted>
+<formatted>
+class A
+ begin
+ do_something
+ rescue
+ yeah
+ end
+ var = do_something rescue nil
+ foo
+end
+</formatted>
+</part>
+</test>
+
+<test ID="LineStartingWithParen">
+<part>
+<assertionMessage>Align line starting with paren</assertionMessage>
+<unformatted>
+class A
+ foo
+ (1 - 2).inspect
+end
+</unformatted>
+<formatted>
+class A
+ foo
+ (1 - 2).inspect
+end
+</formatted>
+</part>
+</test>
+
+<test ID="CaseWithWhens">
+<part>
+<assertionMessage>Indent when</assertionMessage>
+<unformatted>
+module Foo
+ def bar
+ case baz
+ when 'sweet harmonious biscuits'
+when 'yuck'
+ when 'eww'
+ end
+ end
+end
+</unformatted>
+<formatted>
+module Foo
+ def bar
+ case baz
+ when 'sweet harmonious biscuits'
+ when 'yuck'
+ when 'eww'
+ end
+ end
+end
+</formatted>
+</part>
+</test>
+
+</tests>
+
Property changes on: trunk/org.rubypeople.rdt.core.tests/src/org/rubypeople/rdt/internal/formatter/TC_ASTBasedCodeFormatter_Data.xml
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Modified: trunk/org.rubypeople.rdt.core.tests/src/org/rubypeople/rdt/internal/formatter/TC_CodeFormatter.java
===================================================================
--- trunk/org.rubypeople.rdt.core.tests/src/org/rubypeople/rdt/internal/formatter/TC_CodeFormatter.java 2007-08-22 16:39:58 UTC (rev 3044)
+++ trunk/org.rubypeople.rdt.core.tests/src/org/rubypeople/rdt/internal/formatter/TC_CodeFormatter.java 2007-08-22 16:40:08 UTC (rev 3045)
@@ -1,6 +1,7 @@
package org.rubypeople.rdt.internal.formatter;
import java.io.IOException;
+import java.io.InputStream;
import java.util.ArrayList;
import java.util.Hashtable;
@@ -11,6 +12,11 @@
import junit.framework.Assert;
import junit.framework.TestCase;
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.text.edits.MalformedTreeException;
+import org.eclipse.text.edits.TextEdit;
+import org.rubypeople.rdt.core.formatter.CodeFormatter;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
@@ -44,7 +50,7 @@
}
public void parseXmlConfiguration() throws SAXException, IOException, ParserConfigurationException, FactoryConfigurationError {
- Document document = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(this.getClass().getResourceAsStream("FormatTestData.xml"));
+ Document document = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(getInputDataStream());
NodeList tests = document.getElementsByTagName("test");
for (int i = 0; i < tests.getLength(); i++) {
Node test = tests.item(i);
@@ -62,6 +68,10 @@
}
}
+ protected InputStream getInputDataStream() {
+ return this.getClass().getResourceAsStream("FormatTestData.xml");
+ }
+
private void createTestData(ArrayList partList, NodeList partNodes) {
String formattedText = null;
String unformattedText = null;
@@ -84,8 +94,17 @@
public void doTest(String name) {
ArrayList partList = (ArrayList) testMap.get(name);
for (int i = 0; i < partList.size(); i++) {
- TestData data = (TestData) partList.get(i);
- String formatted = new OldCodeFormatter().formatString(data.unformattedText);
+ TestData data = (TestData) partList.get(i);
+ TextEdit edit = getCodeFormatter().format(-1, data.unformattedText, 0, data.unformattedText.length(), 0, "\n");
+ IDocument doc = new org.eclipse.jface.text.Document(data.unformattedText);
+ try {
+ edit.apply(doc);
+ } catch (MalformedTreeException e) {
+ fail(e.getMessage());
+ } catch (BadLocationException e) {
+ fail(e.getMessage());
+ }
+ String formatted = doc.get();
log("---------- " + data.assertionMessage + " --------") ;
log(data.unformattedText) ;
log("------------") ;
@@ -94,6 +113,10 @@
}
}
+ protected CodeFormatter getCodeFormatter() {
+ return new OldCodeFormatter();
+ }
+
private void log(String formatted) {
if (VERBOSE)
System.out.println(formatted);
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|