[#1443] Fix XtextFormatter behaviour on different line endings.

- Modify the FormattingConfigBasedStream to handle the different line
endings properly.
- Implement corresponding XtextFormatterTest and
GrammarAccessExtensions2Test test cases.

Signed-off-by: Tamas Miklossy <miklossy@itemis.de>
This commit is contained in:
Tamas Miklossy 2020-05-12 20:07:56 +02:00
parent b66b4c6186
commit 7b0469e1cc
5 changed files with 789 additions and 3 deletions

View file

@ -0,0 +1,182 @@
/*******************************************************************************
* Copyright (c) 2020 itemis AG (http://www.itemis.eu) and others.
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0.
*
* SPDX-License-Identifier: EPL-2.0
*******************************************************************************/
package org.eclipse.xtext.xtext
import com.google.inject.Inject
import org.eclipse.xtext.Grammar
import org.eclipse.xtext.formatting.INodeModelFormatter
import org.eclipse.xtext.testing.InjectWith
import org.eclipse.xtext.testing.XtextRunner
import org.eclipse.xtext.testing.util.ParseHelper
import org.eclipse.xtext.tests.XtextInjectorProvider
import org.junit.Test
import org.junit.runner.RunWith
import org.eclipse.xtext.resource.XtextResource
import static extension org.junit.Assert.assertEquals
import static extension org.eclipse.xtext.util.Strings.toUnixLineSeparator
/**
* Test cases for the {@link XtextFormatter} class.
*
* @author miklossy - Initial contribution and API
*/
@RunWith(XtextRunner)
@InjectWith(XtextInjectorProvider)
class XtextFormatterTest {
@Inject extension ParseHelper<Grammar>
@Inject extension INodeModelFormatter
@Test def formatting_with_windows_line_endings01() {
'''
grammar org.xtext.example.mydsl.MyDsl
generate myDsl "http://www.xtext.org/example/mydsl/MyDsl"
OpOther:
'->'
| '..<'
| '>' '..'
| '..'
| '=>'
| '>' (=>('>' '>') | '>')
| '<' (=>('<' '<') | '<' | '=>')
| '<>'
| '?:';'''
.assertFormattedAs('''
grammar org.xtext.example.mydsl.MyDsl
generate myDsl "http://www.xtext.org/example/mydsl/MyDsl"
OpOther:
'->'
| '..<'
| '>' '..'
| '..'
| '=>'
| '>' (=> ('>' '>') | '>')
| '<' (=> ('<' '<') | '<' | '=>')
| '<>'
| '?:';'''
)
}
@Test def formatting_with_windows_line_endings02() {
'''
grammar org.xtext.example.mydsl.MyDsl
generate myDsl "http://www.xtext.org/example/mydsl/MyDsl"
OpOther:
'->'
| '..<'
| '>' '..'
| '..'
| '=>'
| '>' (=>('>' '>') | '>')
| '<' (=>('<' '<') | '<' | '=>')
| '<>'
| '?:';
'''.assertFormattedAs('''
grammar org.xtext.example.mydsl.MyDsl
generate myDsl "http://www.xtext.org/example/mydsl/MyDsl"
OpOther:
'->'
| '..<'
| '>' '..'
| '..'
| '=>'
| '>' (=> ('>' '>') | '>')
| '<' (=> ('<' '<') | '<' | '=>')
| '<>'
| '?:';'''
)
}
@Test def formatting_with_unix_line_endings01() {
'''
grammar org.xtext.example.mydsl.MyDsl
generate myDsl "http://www.xtext.org/example/mydsl/MyDsl"
OpOther:
'->'
| '..<'
| '>' '..'
| '..'
| '=>'
| '>' (=>('>' '>') | '>')
| '<' (=>('<' '<') | '<' | '=>')
| '<>'
| '?:';'''
.toUnixLineSeparator.assertFormattedAs('''
grammar org.xtext.example.mydsl.MyDsl
generate myDsl "http://www.xtext.org/example/mydsl/MyDsl"
OpOther:
'->'
| '..<'
| '>' '..'
| '..'
| '=>'
| '>' (=> ('>' '>') | '>')
| '<' (=> ('<' '<') | '<' | '=>')
| '<>'
| '?:';'''
)
}
@Test def formatting_with_unix_line_endings02() {
'''
grammar org.xtext.example.mydsl.MyDsl
generate myDsl "http://www.xtext.org/example/mydsl/MyDsl"
OpOther:
'->'
| '..<'
| '>' '..'
| '..'
| '=>'
| '>' (=>('>' '>') | '>')
| '<' (=>('<' '<') | '<' | '=>')
| '<>'
| '?:';
'''.toUnixLineSeparator.assertFormattedAs('''
grammar org.xtext.example.mydsl.MyDsl
generate myDsl "http://www.xtext.org/example/mydsl/MyDsl"
OpOther:
'->'
| '..<'
| '>' '..'
| '..'
| '=>'
| '>' (=> ('>' '>') | '>')
| '<' (=> ('<' '<') | '<' | '=>')
| '<>'
| '?:';'''
)
}
private def assertFormattedAs(CharSequence input, CharSequence expected) {
expected.toString.assertEquals(input.formattedText)
}
private def formattedText(CharSequence unformattedText) {
val rootNode = (unformattedText.parse.eResource as XtextResource).parseResult.rootNode
rootNode.format(0, unformattedText.length).formattedText
}
}

View file

@ -0,0 +1,90 @@
/*******************************************************************************
* Copyright (c) 2020 itemis AG (http://www.itemis.eu) and others.
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0.
*
* SPDX-License-Identifier: EPL-2.0
*******************************************************************************/
package org.eclipse.xtext.xtext.generator
import com.google.inject.Binder
import com.google.inject.Guice
import com.google.inject.Inject
import com.google.inject.Module
import org.eclipse.xtext.Grammar
import org.eclipse.xtext.XtextRuntimeModule
import org.eclipse.xtext.common.TerminalsStandaloneSetup
import org.eclipse.xtext.testing.IInjectorProvider
import org.eclipse.xtext.testing.InjectWith
import org.eclipse.xtext.testing.XtextRunner
import org.eclipse.xtext.testing.util.ParseHelper
import org.eclipse.xtext.xtext.generator.grammarAccess.GrammarAccessExtensions
import org.eclipse.xtext.xtext.generator.model.project.IXtextProjectConfig
import org.eclipse.xtext.xtext.generator.model.project.StandardProjectConfig
import org.junit.Assert
import org.junit.Test
import org.junit.runner.RunWith
import static extension org.eclipse.xtext.util.Strings.toUnixLineSeparator
/**
* @author miklossy - Initial contribution and API
*/
@RunWith(XtextRunner)
@InjectWith(XtextInjectorProvider)
class GrammarAccessExtensions2Test {
@Inject extension ParseHelper<Grammar>
@Inject extension GrammarAccessExtensions
@Test def testGrammarFragmentToString() {
'''
grammar org.xtext.example.mydsl.MyDsl
generate myDsl "http://www.xtext.org/example/mydsl/MyDsl"
OpOther:
'->'
| '..<'
| '>' '..'
| '..'
| '=>'
| '>' (=>('>' '>') | '>')
| '<' (=>('<' '<') | '<' | '=>')
| '<>'
| '?:';
'''.firstRuleIsConvertedTo('''
//OpOther:
// '->'
// | '..<'
// | '>' '..'
// | '..'
// | '=>'
// | '>' (=> ('>' '>') | '>') | '<' (=> ('<' '<') | '<' | '=>') | '<>'
// | '?:';
''')
}
private def firstRuleIsConvertedTo(CharSequence text, CharSequence expected) {
val actual = text.toUnixLineSeparator.parse.rules.head.grammarFragmentToString("//")
Assert.assertEquals(expected.toString.trim, actual)
}
static class XtextInjectorProvider implements IInjectorProvider {
override getInjector() {
TerminalsStandaloneSetup.doSetup
Guice.createInjector(new XtextRuntimeModule(), new Module() {
override configure(Binder binder) {
binder.bind(IXtextProjectConfig).toInstance(new StandardProjectConfig)
}
})
}
}
}

View file

@ -0,0 +1,367 @@
/**
* Copyright (c) 2020 itemis AG (http://www.itemis.eu) and others.
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0.
*
* SPDX-License-Identifier: EPL-2.0
*/
package org.eclipse.xtext.xtext;
import com.google.inject.Inject;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.xtend2.lib.StringConcatenation;
import org.eclipse.xtext.Grammar;
import org.eclipse.xtext.formatting.INodeModelFormatter;
import org.eclipse.xtext.nodemodel.ICompositeNode;
import org.eclipse.xtext.resource.XtextResource;
import org.eclipse.xtext.testing.InjectWith;
import org.eclipse.xtext.testing.XtextRunner;
import org.eclipse.xtext.testing.util.ParseHelper;
import org.eclipse.xtext.tests.XtextInjectorProvider;
import org.eclipse.xtext.util.Strings;
import org.eclipse.xtext.xbase.lib.Exceptions;
import org.eclipse.xtext.xbase.lib.Extension;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
/**
* Test cases for the {@link XtextFormatter} class.
*
* @author miklossy - Initial contribution and API
*/
@RunWith(XtextRunner.class)
@InjectWith(XtextInjectorProvider.class)
@SuppressWarnings("all")
public class XtextFormatterTest {
@Inject
@Extension
private ParseHelper<Grammar> _parseHelper;
@Inject
@Extension
private INodeModelFormatter _iNodeModelFormatter;
@Test
public void formatting_with_windows_line_endings01() {
StringConcatenation _builder = new StringConcatenation();
_builder.append("grammar org.xtext.example.mydsl.MyDsl");
_builder.newLine();
_builder.newLine();
_builder.append("generate myDsl \"http://www.xtext.org/example/mydsl/MyDsl\"");
_builder.newLine();
_builder.newLine();
_builder.append("OpOther:");
_builder.newLine();
_builder.append("\t ");
_builder.append("\'->\'");
_builder.newLine();
_builder.append("\t");
_builder.append("| \'..<\'");
_builder.newLine();
_builder.append("\t");
_builder.append("| \'>\' \'..\'");
_builder.newLine();
_builder.append("\t");
_builder.append("| \'..\'");
_builder.newLine();
_builder.append("\t");
_builder.append("| \'=>\'");
_builder.newLine();
_builder.append("\t");
_builder.append("| \'>\' (=>(\'>\' \'>\') | \'>\')");
_builder.newLine();
_builder.append("\t");
_builder.append("| \'<\' (=>(\'<\' \'<\') | \'<\' | \'=>\')");
_builder.newLine();
_builder.append("\t");
_builder.append("| \'<>\'");
_builder.newLine();
_builder.append("\t");
_builder.append("| \'?:\';");
StringConcatenation _builder_1 = new StringConcatenation();
_builder_1.append("grammar org.xtext.example.mydsl.MyDsl");
_builder_1.newLine();
_builder_1.newLine();
_builder_1.append("generate myDsl \"http://www.xtext.org/example/mydsl/MyDsl\"");
_builder_1.newLine();
_builder_1.newLine();
_builder_1.append("OpOther:");
_builder_1.newLine();
_builder_1.append("\t");
_builder_1.append("\'->\'");
_builder_1.newLine();
_builder_1.append("\t");
_builder_1.append("| \'..<\'");
_builder_1.newLine();
_builder_1.append("\t");
_builder_1.append("| \'>\' \'..\'");
_builder_1.newLine();
_builder_1.append("\t");
_builder_1.append("| \'..\'");
_builder_1.newLine();
_builder_1.append("\t");
_builder_1.append("| \'=>\'");
_builder_1.newLine();
_builder_1.append("\t");
_builder_1.append("| \'>\' (=> (\'>\' \'>\') | \'>\')");
_builder_1.newLine();
_builder_1.append("\t");
_builder_1.append("| \'<\' (=> (\'<\' \'<\') | \'<\' | \'=>\')");
_builder_1.newLine();
_builder_1.append("\t");
_builder_1.append("| \'<>\'");
_builder_1.newLine();
_builder_1.append("\t");
_builder_1.append("| \'?:\';");
this.assertFormattedAs(_builder, _builder_1);
}
@Test
public void formatting_with_windows_line_endings02() {
StringConcatenation _builder = new StringConcatenation();
_builder.append("grammar org.xtext.example.mydsl.MyDsl");
_builder.newLine();
_builder.newLine();
_builder.append("generate myDsl \"http://www.xtext.org/example/mydsl/MyDsl\"");
_builder.newLine();
_builder.newLine();
_builder.append("OpOther:");
_builder.newLine();
_builder.append("\t ");
_builder.append("\'->\'");
_builder.newLine();
_builder.append("\t");
_builder.append("| \'..<\'");
_builder.newLine();
_builder.append("\t");
_builder.append("| \'>\' \'..\'");
_builder.newLine();
_builder.append("\t");
_builder.append("| \'..\'");
_builder.newLine();
_builder.append("\t");
_builder.append("| \'=>\'");
_builder.newLine();
_builder.append("\t");
_builder.append("| \'>\' (=>(\'>\' \'>\') | \'>\')");
_builder.newLine();
_builder.append("\t");
_builder.append("| \'<\' (=>(\'<\' \'<\') | \'<\' | \'=>\')");
_builder.newLine();
_builder.append("\t");
_builder.append("| \'<>\'");
_builder.newLine();
_builder.append("\t");
_builder.append("| \'?:\';");
_builder.newLine();
StringConcatenation _builder_1 = new StringConcatenation();
_builder_1.append("grammar org.xtext.example.mydsl.MyDsl");
_builder_1.newLine();
_builder_1.newLine();
_builder_1.append("generate myDsl \"http://www.xtext.org/example/mydsl/MyDsl\"");
_builder_1.newLine();
_builder_1.newLine();
_builder_1.append("OpOther:");
_builder_1.newLine();
_builder_1.append("\t");
_builder_1.append("\'->\'");
_builder_1.newLine();
_builder_1.append("\t");
_builder_1.append("| \'..<\'");
_builder_1.newLine();
_builder_1.append("\t");
_builder_1.append("| \'>\' \'..\'");
_builder_1.newLine();
_builder_1.append("\t");
_builder_1.append("| \'..\'");
_builder_1.newLine();
_builder_1.append("\t");
_builder_1.append("| \'=>\'");
_builder_1.newLine();
_builder_1.append("\t");
_builder_1.append("| \'>\' (=> (\'>\' \'>\') | \'>\')");
_builder_1.newLine();
_builder_1.append("\t");
_builder_1.append("| \'<\' (=> (\'<\' \'<\') | \'<\' | \'=>\')");
_builder_1.newLine();
_builder_1.append("\t");
_builder_1.append("| \'<>\'");
_builder_1.newLine();
_builder_1.append("\t");
_builder_1.append("| \'?:\';");
this.assertFormattedAs(_builder, _builder_1);
}
@Test
public void formatting_with_unix_line_endings01() {
StringConcatenation _builder = new StringConcatenation();
_builder.append("grammar org.xtext.example.mydsl.MyDsl");
_builder.newLine();
_builder.newLine();
_builder.append("generate myDsl \"http://www.xtext.org/example/mydsl/MyDsl\"");
_builder.newLine();
_builder.newLine();
_builder.append("OpOther:");
_builder.newLine();
_builder.append("\t ");
_builder.append("\'->\'");
_builder.newLine();
_builder.append("\t");
_builder.append("| \'..<\'");
_builder.newLine();
_builder.append("\t");
_builder.append("| \'>\' \'..\'");
_builder.newLine();
_builder.append("\t");
_builder.append("| \'..\'");
_builder.newLine();
_builder.append("\t");
_builder.append("| \'=>\'");
_builder.newLine();
_builder.append("\t");
_builder.append("| \'>\' (=>(\'>\' \'>\') | \'>\')");
_builder.newLine();
_builder.append("\t");
_builder.append("| \'<\' (=>(\'<\' \'<\') | \'<\' | \'=>\')");
_builder.newLine();
_builder.append("\t");
_builder.append("| \'<>\'");
_builder.newLine();
_builder.append("\t");
_builder.append("| \'?:\';");
String _unixLineSeparator = Strings.toUnixLineSeparator(_builder);
StringConcatenation _builder_1 = new StringConcatenation();
_builder_1.append("grammar org.xtext.example.mydsl.MyDsl");
_builder_1.newLine();
_builder_1.newLine();
_builder_1.append("generate myDsl \"http://www.xtext.org/example/mydsl/MyDsl\"");
_builder_1.newLine();
_builder_1.newLine();
_builder_1.append("OpOther:");
_builder_1.newLine();
_builder_1.append("\t");
_builder_1.append("\'->\'");
_builder_1.newLine();
_builder_1.append("\t");
_builder_1.append("| \'..<\'");
_builder_1.newLine();
_builder_1.append("\t");
_builder_1.append("| \'>\' \'..\'");
_builder_1.newLine();
_builder_1.append("\t");
_builder_1.append("| \'..\'");
_builder_1.newLine();
_builder_1.append("\t");
_builder_1.append("| \'=>\'");
_builder_1.newLine();
_builder_1.append("\t");
_builder_1.append("| \'>\' (=> (\'>\' \'>\') | \'>\')");
_builder_1.newLine();
_builder_1.append("\t");
_builder_1.append("| \'<\' (=> (\'<\' \'<\') | \'<\' | \'=>\')");
_builder_1.newLine();
_builder_1.append("\t");
_builder_1.append("| \'<>\'");
_builder_1.newLine();
_builder_1.append("\t");
_builder_1.append("| \'?:\';");
this.assertFormattedAs(_unixLineSeparator, _builder_1);
}
@Test
public void formatting_with_unix_line_endings02() {
StringConcatenation _builder = new StringConcatenation();
_builder.append("grammar org.xtext.example.mydsl.MyDsl");
_builder.newLine();
_builder.newLine();
_builder.append("generate myDsl \"http://www.xtext.org/example/mydsl/MyDsl\"");
_builder.newLine();
_builder.newLine();
_builder.append("OpOther:");
_builder.newLine();
_builder.append("\t ");
_builder.append("\'->\'");
_builder.newLine();
_builder.append("\t");
_builder.append("| \'..<\'");
_builder.newLine();
_builder.append("\t");
_builder.append("| \'>\' \'..\'");
_builder.newLine();
_builder.append("\t");
_builder.append("| \'..\'");
_builder.newLine();
_builder.append("\t");
_builder.append("| \'=>\'");
_builder.newLine();
_builder.append("\t");
_builder.append("| \'>\' (=>(\'>\' \'>\') | \'>\')");
_builder.newLine();
_builder.append("\t");
_builder.append("| \'<\' (=>(\'<\' \'<\') | \'<\' | \'=>\')");
_builder.newLine();
_builder.append("\t");
_builder.append("| \'<>\'");
_builder.newLine();
_builder.append("\t");
_builder.append("| \'?:\';");
_builder.newLine();
String _unixLineSeparator = Strings.toUnixLineSeparator(_builder);
StringConcatenation _builder_1 = new StringConcatenation();
_builder_1.append("grammar org.xtext.example.mydsl.MyDsl");
_builder_1.newLine();
_builder_1.newLine();
_builder_1.append("generate myDsl \"http://www.xtext.org/example/mydsl/MyDsl\"");
_builder_1.newLine();
_builder_1.newLine();
_builder_1.append("OpOther:");
_builder_1.newLine();
_builder_1.append("\t");
_builder_1.append("\'->\'");
_builder_1.newLine();
_builder_1.append("\t");
_builder_1.append("| \'..<\'");
_builder_1.newLine();
_builder_1.append("\t");
_builder_1.append("| \'>\' \'..\'");
_builder_1.newLine();
_builder_1.append("\t");
_builder_1.append("| \'..\'");
_builder_1.newLine();
_builder_1.append("\t");
_builder_1.append("| \'=>\'");
_builder_1.newLine();
_builder_1.append("\t");
_builder_1.append("| \'>\' (=> (\'>\' \'>\') | \'>\')");
_builder_1.newLine();
_builder_1.append("\t");
_builder_1.append("| \'<\' (=> (\'<\' \'<\') | \'<\' | \'=>\')");
_builder_1.newLine();
_builder_1.append("\t");
_builder_1.append("| \'<>\'");
_builder_1.newLine();
_builder_1.append("\t");
_builder_1.append("| \'?:\';");
this.assertFormattedAs(_unixLineSeparator, _builder_1);
}
private void assertFormattedAs(final CharSequence input, final CharSequence expected) {
Assert.assertEquals(expected.toString(), this.formattedText(input));
}
private String formattedText(final CharSequence unformattedText) {
try {
String _xblockexpression = null;
{
Resource _eResource = this._parseHelper.parse(unformattedText).eResource();
final ICompositeNode rootNode = ((XtextResource) _eResource).getParseResult().getRootNode();
_xblockexpression = this._iNodeModelFormatter.format(rootNode, 0, unformattedText.length()).getFormattedText();
}
return _xblockexpression;
} catch (Throwable _e) {
throw Exceptions.sneakyThrow(_e);
}
}
}

View file

@ -0,0 +1,137 @@
/**
* Copyright (c) 2020 itemis AG (http://www.itemis.eu) and others.
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0.
*
* SPDX-License-Identifier: EPL-2.0
*/
package org.eclipse.xtext.xtext.generator;
import com.google.inject.Binder;
import com.google.inject.Guice;
import com.google.inject.Inject;
import com.google.inject.Injector;
import com.google.inject.binder.AnnotatedBindingBuilder;
import org.eclipse.xtend2.lib.StringConcatenation;
import org.eclipse.xtext.AbstractRule;
import org.eclipse.xtext.Grammar;
import org.eclipse.xtext.XtextRuntimeModule;
import org.eclipse.xtext.common.TerminalsStandaloneSetup;
import org.eclipse.xtext.testing.IInjectorProvider;
import org.eclipse.xtext.testing.InjectWith;
import org.eclipse.xtext.testing.XtextRunner;
import org.eclipse.xtext.testing.util.ParseHelper;
import org.eclipse.xtext.util.Strings;
import org.eclipse.xtext.xbase.lib.Exceptions;
import org.eclipse.xtext.xbase.lib.Extension;
import org.eclipse.xtext.xbase.lib.IterableExtensions;
import org.eclipse.xtext.xtext.generator.grammarAccess.GrammarAccessExtensions;
import org.eclipse.xtext.xtext.generator.model.project.IXtextProjectConfig;
import org.eclipse.xtext.xtext.generator.model.project.StandardProjectConfig;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
/**
* @author miklossy - Initial contribution and API
*/
@RunWith(XtextRunner.class)
@InjectWith(GrammarAccessExtensions2Test.XtextInjectorProvider.class)
@SuppressWarnings("all")
public class GrammarAccessExtensions2Test {
public static class XtextInjectorProvider implements IInjectorProvider {
@Override
public Injector getInjector() {
Injector _xblockexpression = null;
{
TerminalsStandaloneSetup.doSetup();
XtextRuntimeModule _xtextRuntimeModule = new XtextRuntimeModule();
_xblockexpression = Guice.createInjector(_xtextRuntimeModule, new com.google.inject.Module() {
@Override
public void configure(final Binder binder) {
AnnotatedBindingBuilder<IXtextProjectConfig> _bind = binder.<IXtextProjectConfig>bind(IXtextProjectConfig.class);
StandardProjectConfig _standardProjectConfig = new StandardProjectConfig();
_bind.toInstance(_standardProjectConfig);
}
});
}
return _xblockexpression;
}
}
@Inject
@Extension
private ParseHelper<Grammar> _parseHelper;
@Inject
@Extension
private GrammarAccessExtensions _grammarAccessExtensions;
@Test
public void testGrammarFragmentToString() {
StringConcatenation _builder = new StringConcatenation();
_builder.append("grammar org.xtext.example.mydsl.MyDsl");
_builder.newLine();
_builder.newLine();
_builder.append("generate myDsl \"http://www.xtext.org/example/mydsl/MyDsl\"");
_builder.newLine();
_builder.newLine();
_builder.append("OpOther:");
_builder.newLine();
_builder.append("\t ");
_builder.append("\'->\'");
_builder.newLine();
_builder.append("\t");
_builder.append("| \'..<\'");
_builder.newLine();
_builder.append("\t");
_builder.append("| \'>\' \'..\'");
_builder.newLine();
_builder.append("\t");
_builder.append("| \'..\'");
_builder.newLine();
_builder.append("\t");
_builder.append("| \'=>\'");
_builder.newLine();
_builder.append("\t");
_builder.append("| \'>\' (=>(\'>\' \'>\') | \'>\')");
_builder.newLine();
_builder.append("\t");
_builder.append("| \'<\' (=>(\'<\' \'<\') | \'<\' | \'=>\')");
_builder.newLine();
_builder.append("\t");
_builder.append("| \'<>\'");
_builder.newLine();
_builder.append("\t");
_builder.append("| \'?:\';");
_builder.newLine();
StringConcatenation _builder_1 = new StringConcatenation();
_builder_1.append("//OpOther:");
_builder_1.newLine();
_builder_1.append("//\t\'->\'");
_builder_1.newLine();
_builder_1.append("//\t| \'..<\'");
_builder_1.newLine();
_builder_1.append("//\t| \'>\' \'..\'");
_builder_1.newLine();
_builder_1.append("//\t| \'..\'");
_builder_1.newLine();
_builder_1.append("//\t| \'=>\'");
_builder_1.newLine();
_builder_1.append("//\t| \'>\' (=> (\'>\' \'>\') | \'>\') | \'<\' (=> (\'<\' \'<\') | \'<\' | \'=>\') | \'<>\'");
_builder_1.newLine();
_builder_1.append("//\t| \'?:\';");
_builder_1.newLine();
this.firstRuleIsConvertedTo(_builder, _builder_1);
}
private void firstRuleIsConvertedTo(final CharSequence text, final CharSequence expected) {
try {
final String actual = this._grammarAccessExtensions.grammarFragmentToString(IterableExtensions.<AbstractRule>head(this._parseHelper.parse(Strings.toUnixLineSeparator(text)).getRules()), "//");
Assert.assertEquals(expected.toString().trim(), actual);
} catch (Throwable _e) {
throw Exceptions.sneakyThrow(_e);
}
}
}

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2009 itemis AG (http://www.itemis.eu) and others.
* Copyright (c) 2009, 2020 itemis AG (http://www.itemis.eu) and others.
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0.
@ -494,9 +494,9 @@ public class FormattingConfigBasedStream extends BaseTokenStream {
&& hiddenTokenHelper.isWhitespace((AbstractRule) grammarElement);
if (isWhitespace || cfg.getWhitespaceRule() == grammarElement) {
if (preservedWS == null)
preservedWS = value;
preservedWS = harmonizeLineSeparator(value);
else
preservedWS += value;
preservedWS += harmonizeLineSeparator(value);
} else
addLineEntry(grammarElement, value, true);
}
@ -505,4 +505,14 @@ public class FormattingConfigBasedStream extends BaseTokenStream {
public void writeSemantic(EObject grammarElement, String value) throws IOException {
addLineEntry(grammarElement, value, false);
}
/**
* @since 2.22
*/
protected String harmonizeLineSeparator(String value) {
if (value != null) {
return value.replaceAll("\r?\n", getLineSeparator());
}
return null;
}
}