This commit is contained in:
sefftinge 2008-10-09 12:55:46 +00:00
parent a4c8f50b9c
commit fa3338fe7f
15 changed files with 115 additions and 97 deletions

View file

@ -34,5 +34,4 @@ Require-Bundle: org.eclipse.xtext.log4j;bundle-version="1.2.15",
org.eclipse.xtext.service;visibility:=reexport,
org.eclipse.xtext.util,
org.junit;resolution:=optional,
org.eclipse.xtend.util.stdlib,
org.antlr.runtime;bundle-version="3.0.0";visibility:=reexport

View file

@ -2,6 +2,6 @@ log4j.rootLogger=debug, default
log4j.appender.default=org.apache.log4j.ConsoleAppender
log4j.appender.default.layout=org.apache.log4j.PatternLayout
log4j.appender.default.layout.ConversionPattern=%-4r [%t] %-5p %c %x - %m%n
log4j.appender.default.layout.ConversionPattern=%-4r [%t] %-5p %35.35c %x - %m%n
log4j.logger.org.eclipse.xtext=DEBUG

View file

@ -8,13 +8,21 @@
*******************************************************************************/
package org.eclipse.xtext.parsetree.reconstr;
import java.io.OutputStream;
import java.util.Map;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.xtext.service.ILanguageService;
/**
* @author Sven Efftinge - Initial contribution and API
*
*
*/
// TODO: rename to ISerializer
public interface IParseTreeConstructor extends ILanguageService {
public void update(EObject object, IParseTreeConstructorCallback callback);
public static final String OPTION_SERIALIZER_STRATEGY = "OPTION_SERIALIZER_STRATEGY";
public void serialize(OutputStream outputStream, EObject object, Map<?, ?> options);
}

View file

@ -8,12 +8,15 @@
*******************************************************************************/
package org.eclipse.xtext.parsetree.reconstr;
import java.io.OutputStream;
import org.eclipse.xtext.Action;
import org.eclipse.xtext.CrossReference;
import org.eclipse.xtext.Keyword;
import org.eclipse.xtext.RuleCall;
import org.eclipse.xtext.service.ILanguageService;
// TODO: rename to ISerializerStrategy
public interface IParseTreeConstructorCallback extends ILanguageService {
void parserRuleCallStart(IInstanceDescription current, RuleCall call);
@ -34,7 +37,7 @@ public interface IParseTreeConstructorCallback extends ILanguageService {
void crossRefCall(IInstanceDescription current, CrossReference call);
void beginSerialize();
void beginSerialize(OutputStream output);
void endSerialize();
}

View file

@ -8,6 +8,8 @@
*******************************************************************************/
package org.eclipse.xtext.parsetree.reconstr.callbacks;
import java.io.OutputStream;
import org.eclipse.xtext.Action;
import org.eclipse.xtext.CrossReference;
import org.eclipse.xtext.Keyword;
@ -41,10 +43,9 @@ public class DefaultParsetreeReconstructorCallback implements IParseTreeConstruc
public void lexerRuleCall(IInstanceDescription current, RuleCall call) {
}
public void beginSerialize() {
public void beginSerialize(OutputStream output) {
}
public void endSerialize() {
}
}

View file

@ -12,19 +12,17 @@ import org.eclipse.xtext.Keyword;
import org.eclipse.xtext.RuleCall;
import org.eclipse.xtext.conversion.IValueConverterService;
import org.eclipse.xtext.parsetree.reconstr.IInstanceDescription;
import org.eclipse.xtext.service.Inject;
public class SimpleSerializingCallback extends
DefaultParsetreeReconstructorCallback {
protected final OutputStream out;
protected final IValueConverterService converterService;
protected boolean outputHasStarted;
@Inject
protected IValueConverterService converterService;
public SimpleSerializingCallback(OutputStream output,
IValueConverterService converterService) {
this.converterService = converterService;
this.out = output;
}
protected OutputStream out;
protected boolean outputHasStarted;
protected void append(String str) {
try {
@ -43,9 +41,10 @@ public class SimpleSerializingCallback extends
append(" ");
}
public void beginSerialize() {
super.beginSerialize();
public void beginSerialize(OutputStream output) {
super.beginSerialize(output);
outputHasStarted = false;
out = output;
}
public void crossRefCall(IInstanceDescription current, CrossReference call) {
@ -65,6 +64,10 @@ public class SimpleSerializingCallback extends
+ object);
}
public IValueConverterService getConverterService() {
return converterService;
}
public void keywordCall(IInstanceDescription current, Keyword call) {
before(current, call);
append(call.getValue());
@ -75,4 +78,8 @@ public class SimpleSerializingCallback extends
before(current, call);
append(converterService.toString(value, call.getName()));
}
public void setConverterService(IValueConverterService converterService) {
this.converterService = converterService;
}
}

View file

@ -6,7 +6,6 @@ import java.util.List;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.xtext.AbstractElement;
import org.eclipse.xtext.Assignment;
import org.eclipse.xtext.conversion.IValueConverterService;
import org.eclipse.xtext.parsetree.CompositeNode;
import org.eclipse.xtext.parsetree.LeafNode;
import org.eclipse.xtext.parsetree.NodeAdapter;
@ -19,10 +18,6 @@ public class WhitespacePreservingCallback extends SimpleSerializingCallback {
private int lastLeaf = -1;
public WhitespacePreservingCallback(OutputStream output,
IValueConverterService converterService) {
super(output, converterService);
}
protected void before(IInstanceDescription curr, AbstractElement ele) {
int i = lastLeaf, last = findLeafNodeFor(curr, ele);
@ -36,7 +31,8 @@ public class WhitespacePreservingCallback extends SimpleSerializingCallback {
}
}
public void beginSerialize() {
public void beginSerialize(OutputStream output) {
super.beginSerialize(output);
lastLeaf = -1;
allLeafs = null;
}

View file

@ -1,23 +1,20 @@
package org.eclipse.xtext.parsetree.reconstr.impl;
import java.io.ByteArrayOutputStream;
import java.io.OutputStream;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.Map;
import org.apache.log4j.Logger;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.xtext.Grammar;
import org.eclipse.xtext.GrammarUtil;
import org.eclipse.xtext.IGrammarAccess;
import org.eclipse.xtext.ParserRule;
import org.eclipse.xtext.conversion.IValueConverterService;
import org.eclipse.xtext.parser.IAstFactory;
import org.eclipse.xtext.parsetree.reconstr.IInstanceDescription;
import org.eclipse.xtext.parsetree.reconstr.IParseTreeConstructor;
import org.eclipse.xtext.parsetree.reconstr.IParseTreeConstructorCallback;
import org.eclipse.xtext.parsetree.reconstr.callbacks.SimpleSerializingCallback;
import org.eclipse.xtext.service.Inject;
public abstract class AbstractParseTreeConstructor implements
@ -104,11 +101,12 @@ public abstract class AbstractParseTreeConstructor implements
}
private String dsl(AbstractToken ele) {
ByteArrayOutputStream out = new ByteArrayOutputStream();
SimpleSerializingCallback cb = new SimpleSerializingCallback(out,
converterService);
executeAllCallbacks(cb);
return out.toString();
// ByteArrayOutputStream out = new ByteArrayOutputStream();
// SimpleSerializingCallback cb = new SimpleSerializingCallback(out,
// converterService);
// executeAllCallbacks(cb);
// return out.toString();
return "";
}
public void executeAllCallbacks(IParseTreeConstructorCallback callback) {
@ -123,16 +121,17 @@ public abstract class AbstractParseTreeConstructor implements
}
public Solution firstSolution() {
System.out.println("->" + depth(this) + getClass().getSimpleName()
+ "\t " + current + " -> " + dsl(this));
if (log.isDebugEnabled())
log.debug("->" + depth(this) + getClass().getSimpleName()
+ "\t " + current + " -> " + dsl(this));
Solution t1 = createSolution();
System.out
.println("< "
+ depth(this)
+ getClass().getSimpleName()
+ " -> "
+ ((t1 == null) ? "failed" : "success" + "\t "
+ t1.current));
if (log.isDebugEnabled())
log.debug("< "
+ depth(this)
+ getClass().getSimpleName()
+ " -> "
+ ((t1 == null) ? "failed" : "success" + "\t "
+ t1.current));
if (t1 == null)
return required ? null : new Solution(current, predecessor);
if (many) {
@ -235,8 +234,13 @@ public abstract class AbstractParseTreeConstructor implements
}
protected Logger log = Logger.getLogger(AbstractParseTreeConstructor.class);
@Inject
protected IValueConverterService converterService;
private IParseTreeConstructorCallback serializerStrategy;
@Inject
private IValueConverterService converterService;
@Inject
private IAstFactory factory;
@ -265,18 +269,33 @@ public abstract class AbstractParseTreeConstructor implements
URI.createURI(string), true);
}
protected IValueConverterService getValueConverterService() {
public IValueConverterService getValueConverterService() {
return converterService;
}
protected abstract void internalDoUpdate(EObject obj, String ruleToCall,
IParseTreeConstructorCallback callback);
public static final String OPTION_SERIALIZER_STRATEGY = "OPTION_SERIALIZER_STRATEGY";
public void update(EObject object, IParseTreeConstructorCallback callback) {
EObject root = EcoreUtil.getRootContainer(object);
ParserRule parserRule = GrammarUtil.getDefaultEntryRule(getGrammar());
String ruleToCall = parserRule.getName();
internalDoUpdate(root, ruleToCall, callback);
private IParseTreeConstructorCallback getSerializerStrategy(
Map<?, ?> options) {
Object serObj = options.get(OPTION_SERIALIZER_STRATEGY);
if (serObj == null)
return serializerStrategy;
if (serObj instanceof IParseTreeConstructorCallback)
return (IParseTreeConstructorCallback) serObj;
throw new IllegalStateException("The Object supplied with "
+ OPTION_SERIALIZER_STRATEGY + " needs to be of type "
+ IParseTreeConstructorCallback.class.getName());
}
public void serialize(OutputStream outputStream, EObject object,
Map<?, ?> options) {
IParseTreeConstructorCallback ser = getSerializerStrategy(options);
ser.beginSerialize(outputStream);
internalSerialize(object, ser);
ser.endSerialize();
}
protected abstract void internalSerialize(EObject object,
IParseTreeConstructorCallback strategy);
}

View file

@ -21,7 +21,6 @@ import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.resource.impl.ResourceImpl;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.xtext.conversion.IValueConverterService;
import org.eclipse.xtext.crossref.BrokenLink;
import org.eclipse.xtext.crossref.IFragmentProvider;
import org.eclipse.xtext.crossref.ILinker;
@ -31,7 +30,6 @@ import org.eclipse.xtext.parser.IParser;
import org.eclipse.xtext.parsetree.CompositeNode;
import org.eclipse.xtext.parsetree.NodeContentAdapter;
import org.eclipse.xtext.parsetree.reconstr.IParseTreeConstructor;
import org.eclipse.xtext.parsetree.reconstr.callbacks.WhitespacePreservingCallback;
import org.eclipse.xtext.service.Inject;
/**
@ -55,9 +53,6 @@ public class XtextResource extends ResourceImpl {
@Inject
private IParseTreeConstructor parseTreeConstructor;
@Inject
private IValueConverterService valueConverterService;
private IParseResult parseResult;
public XtextResource(URI uri) {
@ -136,25 +131,11 @@ public class XtextResource extends ResourceImpl {
}
setIntrinsicIDToEObjectMap(map);
}
@Override
public void doSave(OutputStream outputStream, Map<?, ?> options) throws IOException {
if (contents.size() > 1) {
throw new IllegalStateException("Xtext resource cannot contain multiple root elements");
}
if (!contents.isEmpty()) {
EObject rootElement = contents.get(0);
WhitespacePreservingCallback cb = new WhitespacePreservingCallback(
outputStream, valueConverterService);
parseTreeConstructor.update(rootElement, cb);
// outputStream.write(cb.toString().getBytes());
}
if (contents.size() != 1)
throw new IllegalStateException("The Xtext resource must contain exactly one root element");
parseTreeConstructor.serialize(outputStream, contents.get(0), options);
}
// public String serialize(EObject o) {
// WhitespacePreservingCallback cb = new WhitespacePreservingCallback(valueConverterService);
// parseTreeConstructor.update(o, cb);
// return o.toString();
// }
}

View file

@ -1,8 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" path="src"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
<classpathentry kind="src" path="src-gen"/>
<classpathentry kind="src" path="src"/>
<classpathentry kind="output" path="bin"/>
</classpath>

View file

@ -0,0 +1,7 @@
log4j.rootLogger=debug, default
log4j.appender.default=org.apache.log4j.ConsoleAppender
log4j.appender.default.layout=org.apache.log4j.PatternLayout
log4j.appender.default.layout.ConversionPattern=%-4r [%t] %-5p %35.35c %x - %m%n
log4j.logger.org.eclipse=INFO

View file

@ -9,12 +9,12 @@
package org.eclipse.xtext.parsetree.reconstr;
import java.io.ByteArrayOutputStream;
import java.util.Collections;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.xtext.ParserRule;
import org.eclipse.xtext.parsetree.reconstr.callbacks.WhitespacePreservingCallback;
import org.eclipse.xtext.resource.XtextResourceSet;
import org.eclipse.xtext.tests.AbstractGeneratorTest;
import org.eclipse.xtext.tests.EcoreModelComparator;
@ -40,7 +40,6 @@ public class ComplexReconstrTest extends AbstractGeneratorTest {
System.out.println(EmfFormater.objToStr(pr, ""));
}
}
}
public void testSimple() throws Exception {
@ -58,9 +57,7 @@ public class ComplexReconstrTest extends AbstractGeneratorTest {
System.out.println(EmfFormater.objToStr(result, ""));
IParseTreeConstructor con = getParseTreeConstructor();
ByteArrayOutputStream out = new ByteArrayOutputStream();
WhitespacePreservingCallback callback = new WhitespacePreservingCallback(out,
getValueConverterService());
con.update(result, callback);
con.serialize(out, result, Collections.emptyMap());
return out.toString();
}

View file

@ -28,20 +28,20 @@ StrangeStuff :
*/
TrickyA returns TypeA1: TrickyA1 (name += ID)* ({TypeB.x=current} 'x' | {TypeC.x=current} 'y')? name+=STRING;
TrickyA returns TypeA1: 'TA' TrickyA1 (name += ID)* ({TypeB.x=current} 'x' | {TypeC.x=current} 'y')? name+=STRING;
TrickyA1 returns TypeD: name+=ID;
TrickyB : (name = ID type += INT)? (type += ID)*;
TrickyB : 'TB' (name = ID type += INT)? (type += ID)*;
TrickyC : name = ID ({C1.x=current} 'x')? ({C2.y=current} 'y')? ({C3.z=current} 'z')?;
TrickyC : 'TC' name = ID ({C1.x=current} 'x')? ({C2.y=current} 'y')? ({C3.z=current} 'z')?;
TrickyD: (name += INT foo = STRING type += ID)? (name += INT type += ID)? (type += ID)*;
TrickyD: 'TD' (name += INT foo = STRING type += ID)? (name += INT type += ID)? (type += ID)*;
// 34 "abc" XX 123 "de" YY x 34 DD 45 CC
TrickyE: (name+=INT foo+=STRING type+=ID)* 'x' (name+=INT type+=ID)*;
TrickyE: 'TE' (name+=INT foo+=STRING type+=ID)* 'x' (name+=INT type+=ID)*;
//
TrickyF: (name+=ID type+=INT)* (name+=ID | type+=INT);
TrickyF: 'TF' (name+=ID type+=INT)* (name+=ID | type+=INT);
// TrickyG: TrickyG1 | TrickyG2;

View file

@ -9,10 +9,10 @@
package org.eclipse.xtext.parsetree.reconstr;
import java.io.ByteArrayOutputStream;
import java.util.Collections;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.xtext.parsetree.NodeUtil;
import org.eclipse.xtext.parsetree.reconstr.callbacks.WhitespacePreservingCallback;
import org.eclipse.xtext.testlanguages.SimpleExpressionsStandaloneSetup;
import org.eclipse.xtext.tests.AbstractGeneratorTest;
import org.eclipse.xtext.util.EmfFormater;
@ -49,9 +49,7 @@ public class SimpleReconstrTest extends AbstractGeneratorTest {
IParseTreeConstructor con = getParseTreeConstructor();
ByteArrayOutputStream out = new ByteArrayOutputStream();
WhitespacePreservingCallback callback = new WhitespacePreservingCallback(out,
getValueConverterService());
con.update(result, callback);
con.serialize(out, result, Collections.emptyMap());
return out.toString();
}

View file

@ -1,10 +1,9 @@
package org.eclipse.xtext.parsetree.reconstr;
import java.io.ByteArrayOutputStream;
import java.util.Collections;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.xtext.parser.IAstFactory;
import org.eclipse.xtext.parsetree.reconstr.callbacks.WhitespacePreservingCallback;
import org.eclipse.xtext.tests.AbstractGeneratorTest;
public class WhitespacePreservingCallbackTest extends AbstractGeneratorTest {
@ -65,10 +64,14 @@ public class WhitespacePreservingCallbackTest extends AbstractGeneratorTest {
}
private String serialize(EObject result) {
// IParseTreeConstructor con = getParseTreeConstructor();
// ByteArrayOutputStream out = new ByteArrayOutputStream();
// WhitespacePreservingCallback cb = new WhitespacePreservingCallback(out,getValueConverterService());
// con.update(result, cb);
// return out.toString();
IParseTreeConstructor con = getParseTreeConstructor();
ByteArrayOutputStream out = new ByteArrayOutputStream();
WhitespacePreservingCallback cb = new WhitespacePreservingCallback(out,getValueConverterService());
con.update(result, cb);
con.serialize(out, result, Collections.emptyMap());
return out.toString();
}
@ -76,8 +79,7 @@ public class WhitespacePreservingCallbackTest extends AbstractGeneratorTest {
try {
IParseTreeConstructor con = getParseTreeConstructor();
ByteArrayOutputStream out = new ByteArrayOutputStream();
WhitespacePreservingCallback cb = new WhitespacePreservingCallback(out,getValueConverterService());
con.update(o, cb);
con.serialize(out, o, Collections.emptyMap());
fail("Should fail with "+clazz.getSimpleName());
} catch (RuntimeException e) {
if (!clazz.isInstance(e)) {