[eclipse/xtext#1952] converting test code to java

Signed-off-by: Christian Dietrich <christian.dietrich@itemis.de>
This commit is contained in:
Christian Dietrich 2021-04-16 07:00:17 +02:00
parent bc53c4efdb
commit 322a6d2aa7
13 changed files with 2010 additions and 5604 deletions

View file

@ -0,0 +1,803 @@
/**
* Copyright (c) 2014, 2021 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.formatting2.regionaccess.internal;
import java.util.Set;
import javax.inject.Provider;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.xtext.formatting2.debug.TextRegionAccessToString;
import org.eclipse.xtext.formatting2.regionaccess.IHiddenRegion;
import org.eclipse.xtext.formatting2.regionaccess.ILineRegion;
import org.eclipse.xtext.formatting2.regionaccess.ISemanticRegion;
import org.eclipse.xtext.formatting2.regionaccess.ISequentialRegion;
import org.eclipse.xtext.formatting2.regionaccess.ITextRegionAccess;
import org.eclipse.xtext.formatting2.regionaccess.TextRegionAccessBuilder;
import org.eclipse.xtext.formatting2.regionaccess.internal.regionaccesstestlanguage.Root;
import org.eclipse.xtext.formatting2.regionaccess.internal.tests.RegionAccessTestLanguageInjectorProvider;
import org.eclipse.xtext.resource.XtextResource;
import org.eclipse.xtext.serializer.impl.Serializer;
import org.eclipse.xtext.testing.InjectWith;
import org.eclipse.xtext.testing.XtextRunner;
import org.eclipse.xtext.testing.util.ParseHelper;
import org.eclipse.xtext.testing.validation.ValidationTestHelper;
import org.eclipse.xtext.util.Strings;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import com.google.inject.Inject;
/**
* @author Moritz Eysholdt - Initial contribution and API
*/
@InjectWith(RegionAccessTestLanguageInjectorProvider.class)
@RunWith(XtextRunner.class)
public class RegionAccessBuilderTest {
@Inject
private ParseHelper<Root> parseHelper;
@Inject
private Provider<TextRegionAccessBuilder> textRegionAccessBuilder;
@Inject
private ValidationTestHelper validationTestHelper;
@Inject
private Serializer serializer;
@Test
public void testSimple() throws Exception {
String model = "1 foo\n".trim();
String expectation =
"0 0 H\n" +
" B Simple'foo' Root\n" +
"0 1 S \"1\" Simple:'1'\n" +
"1 1 H \" \" Whitespace:TerminalRule'WS'\n" +
"2 3 S \"foo\" Simple:name=ID\n" +
" E Simple'foo' Root\n" +
"5 0 H\n";
assertRegions(model,
expectation);
}
@Test
public void testMultiWhitespace1() throws Exception {
String model = "1 /**/ foo\n".trim();
String expectation =
" 0 0 H\n" +
" B Simple'foo' Root\n" +
" 0 1 S \"1\" Simple:'1'\n" +
" 1 H \" \" Whitespace:TerminalRule'WS'\n" +
" \"/**/\" Comment:TerminalRule'ML_COMMENT' Association:CONTAINER\n" +
" 6 \" \" Whitespace:TerminalRule'WS'\n" +
" 7 3 S \"foo\" Simple:name=ID\n" +
" E Simple'foo' Root\n" +
"10 0 H\n";
assertRegions(model,
expectation);
}
@Test
public void testMultiWhitespace2() throws Exception {
String model =
"1\n" +
"/**/\n" +
"foo\n".trim();
String expectation =
" 0 0 H\n" +
" B Simple'foo' Root\n" +
" 0 1 S \"1\" Simple:'1'\n" +
" 1 H \"\\n" +
"\" Whitespace:TerminalRule'WS'\n" +
" \"/**/\" Comment:TerminalRule'ML_COMMENT' Association:NEXT\n" +
" 6 \"\\n" +
"\" Whitespace:TerminalRule'WS'\n" +
" 7 3 S \"foo\" Simple:name=ID\n" +
" E Simple'foo' Root\n" +
"10 0 H\n";
assertRegions(model,
expectation);
}
@Test
public void testAssignedDelegate() throws Exception {
String model = "2 foo\n".trim();
String expectation =
"0 0 H\n" +
" B Delegation Root\n" +
"0 1 S \"2\" Delegation:'2'\n" +
"1 1 H \" \" Whitespace:TerminalRule'WS'\n" +
" B Delegate'foo' Delegation:delegate=Delegate path:Delegation/delegate\n" +
"2 3 S \"foo\" Delegate:name=ID\n" +
" E Delegate'foo' Delegation:delegate=Delegate path:Delegation/delegate\n" +
" E Delegation Root\n" +
"5 0 H\n";
assertRegions(model,
expectation);
}
@Test
public void testUnassignedDelegate() throws Exception {
String model = "3 foo\n".trim();
String expectation =
"0 0 H\n" +
" B Delegate'foo' Root\n" +
"0 1 S \"3\" Unassigned:'3'\n" +
"1 1 H \" \" Whitespace:TerminalRule'WS'\n" +
"2 3 S \"foo\" Delegate:name=ID\n" +
" E Delegate'foo' Root\n" +
"5 0 H\n";
assertRegions(model,
expectation);
}
@Test
public void testUnassignedPrefixedDelegate() throws Exception {
String model = "4 prefix foo\n".trim();
String expectation =
" 0 0 H\n" +
" B PrefixedUnassigned Root\n" +
" 0 1 S \"4\" PrefixedUnassigned:'4'\n" +
" 1 1 H \" \" Whitespace:TerminalRule'WS'\n" +
" B Delegate'foo' PrefixedUnassigned:delegate=PrefixedDelegate path:PrefixedUnassigned/delegate\n" +
" 2 6 S \"prefix\" PrefixedDelegate:'prefix'\n" +
" 8 1 H \" \" Whitespace:TerminalRule'WS'\n" +
" 9 3 S \"foo\" Delegate:name=ID\n" +
" E Delegate'foo' PrefixedUnassigned:delegate=PrefixedDelegate path:PrefixedUnassigned/delegate\n" +
" E PrefixedUnassigned Root\n" +
"12 0 H\n";
assertRegions(model,
expectation);
}
@Test
public void testExpression1() throws Exception {
String model = "5 a + b\n".trim();
String expectation =
"0 0 H\n" +
" B Add Root\n" +
"0 1 S \"5\" Root:'5'\n" +
"1 1 H \" \" Whitespace:TerminalRule'WS'\n" +
" B Named'a' Expression:{Add.left=} path:Add/left\n" +
"2 1 S \"a\" Primary:name=ID\n" +
" E Named'a' Expression:{Add.left=} path:Add/left\n" +
"3 1 H \" \" Whitespace:TerminalRule'WS'\n" +
"4 1 S \"+\" Expression:'+'\n" +
"5 1 H \" \" Whitespace:TerminalRule'WS'\n" +
" B Named'b' Expression:right=Primary path:Add/right\n" +
"6 1 S \"b\" Primary:name=ID\n" +
" E Named'b' Expression:right=Primary path:Add/right\n" +
" E Add Root\n" +
"7 0 H\n";
assertRegions(model,
expectation);
}
@Test
public void testExpression2() throws Exception {
String model = "5 (a + b) + c\n".trim();
String expectation =
" 0 0 H\n" +
" B Add Root\n" +
" 0 1 S \"5\" Root:'5'\n" +
" 1 1 H \" \" Whitespace:TerminalRule'WS'\n" +
" B Add Expression:{Add.left=} path:Add/left\n" +
" 2 1 S \"(\" Parenthesized:'('\n" +
" 3 0 H\n" +
" B Named'a' Expression:{Add.left=} path:Add/left=Add/left\n" +
" 3 1 S \"a\" Primary:name=ID\n" +
" E Named'a' Expression:{Add.left=} path:Add/left=Add/left\n" +
" 4 1 H \" \" Whitespace:TerminalRule'WS'\n" +
" 5 1 S \"+\" Expression:'+'\n" +
" 6 1 H \" \" Whitespace:TerminalRule'WS'\n" +
" B Named'b' Expression:right=Primary path:Add/right=Add/left\n" +
" 7 1 S \"b\" Primary:name=ID\n" +
" E Named'b' Expression:right=Primary path:Add/right=Add/left\n" +
" 8 0 H\n" +
" 8 1 S \")\" Parenthesized:')'\n" +
" E Add Expression:{Add.left=} path:Add/left\n" +
" 9 1 H \" \" Whitespace:TerminalRule'WS'\n" +
"10 1 S \"+\" Expression:'+'\n" +
"11 1 H \" \" Whitespace:TerminalRule'WS'\n" +
" B Named'c' Expression:right=Primary path:Add/right\n" +
"12 1 S \"c\" Primary:name=ID\n" +
" E Named'c' Expression:right=Primary path:Add/right\n" +
" E Add Root\n" +
"13 0 H\n";
assertRegions(model,
expectation);
}
@Test
public void testMixedUnassignedTerminal() throws Exception {
String model = "6 (unassigned foo)\n".trim();
String expectation =
" 0 0 H\n" +
" B Action Root\n" +
" 0 1 S \"6\" Root:'6'\n" +
" 1 1 H \" \" Whitespace:TerminalRule'WS'\n" +
" 2 1 S \"(\" Mixed:'('\n" +
" 3 0 H\n" +
" 3 10 S \"unass...\" Mixed:'unassigned'\n" +
"13 1 H \" \" Whitespace:TerminalRule'WS'\n" +
"14 3 S \"foo\" Mixed:ID\n" +
"17 0 H\n" +
"17 1 S \")\" Mixed:')'\n" +
" E Action Root\n" +
"18 0 H\n";
assertRegions(model,
expectation);
}
@Test
public void testMixedUnassignedDatatype1() throws Exception {
String model = "6 (unassigned datatype foo)\n".trim();
String expectation =
" 0 0 H\n" +
" B Action Root\n" +
" 0 1 S \"6\" Root:'6'\n" +
" 1 1 H \" \" Whitespace:TerminalRule'WS'\n" +
" 2 1 S \"(\" Mixed:'('\n" +
" 3 0 H\n" +
" 3 10 S \"unass...\" Mixed:'unassigned'\n" +
"13 1 H \" \" Whitespace:TerminalRule'WS'\n" +
"14 12 S \"datat...\" Mixed:Datatype\n" +
"26 0 H\n" +
"26 1 S \")\" Mixed:')'\n" +
" E Action Root\n" +
"27 0 H\n";
assertRegions(model,
expectation);
}
@Test
public void testMixedUnassignedDatatype2() throws Exception {
String model = "6 (unassigned datatype datatype foo)\n".trim();
String expectation =
" 0 0 H\n" +
" B Action Root\n" +
" 0 1 S \"6\" Root:'6'\n" +
" 1 1 H \" \" Whitespace:TerminalRule'WS'\n" +
" 2 1 S \"(\" Mixed:'('\n" +
" 3 0 H\n" +
" 3 10 S \"unass...\" Mixed:'unassigned'\n" +
"13 1 H \" \" Whitespace:TerminalRule'WS'\n" +
"14 21 S \"datat...\" Mixed:Datatype\n" +
"35 0 H\n" +
"35 1 S \")\" Mixed:')'\n" +
" E Action Root\n" +
"36 0 H\n";
assertRegions(model,
expectation);
}
@Test
public void testAction() throws Exception {
String model = "6 ()\n".trim();
String expectation =
"0 0 H\n" +
" B Action Root\n" +
"0 1 S \"6\" Root:'6'\n" +
"1 1 H \" \" Whitespace:TerminalRule'WS'\n" +
"2 1 S \"(\" Mixed:'('\n" +
"3 0 H\n" +
"3 1 S \")\" Mixed:')'\n" +
" E Action Root\n" +
"4 0 H\n";
assertRegions(model,
expectation);
}
@Test
public void testActionDelegate() throws Exception {
String model = "6 (())\n".trim();
String expectation =
"0 0 H\n" +
" B Action Root\n" +
"0 1 S \"6\" Root:'6'\n" +
"1 1 H \" \" Whitespace:TerminalRule'WS'\n" +
"2 1 S \"(\" Mixed:'('\n" +
"3 0 H\n" +
"3 1 S \"(\" Mixed:'('\n" +
"4 0 H\n" +
"4 1 S \")\" Mixed:')'\n" +
"5 0 H\n" +
"5 1 S \")\" Mixed:')'\n" +
" E Action Root\n" +
"6 0 H\n";
assertRegions(model,
expectation);
}
@Test
public void testActionDelegate2() throws Exception {
String model = "6 ((()))\n".trim();
String expectation =
"0 0 H\n" +
" B Action Root\n" +
"0 1 S \"6\" Root:'6'\n" +
"1 1 H \" \" Whitespace:TerminalRule'WS'\n" +
"2 1 S \"(\" Mixed:'('\n" +
"3 0 H\n" +
"3 1 S \"(\" Mixed:'('\n" +
"4 0 H\n" +
"4 1 S \"(\" Mixed:'('\n" +
"5 0 H\n" +
"5 1 S \")\" Mixed:')'\n" +
"6 0 H\n" +
"6 1 S \")\" Mixed:')'\n" +
"7 0 H\n" +
"7 1 S \")\" Mixed:')'\n" +
" E Action Root\n" +
"8 0 H\n";
assertRegions(model,
expectation);
}
@Test
public void testAssignmentDelegate2() throws Exception {
String model = "6 (((foo)))\n".trim();
String expectation =
" 0 0 H\n" +
" B Mixed'foo' Root\n" +
" 0 1 S \"6\" Root:'6'\n" +
" 1 1 H \" \" Whitespace:TerminalRule'WS'\n" +
" 2 1 S \"(\" Mixed:'('\n" +
" 3 0 H\n" +
" 3 1 S \"(\" Mixed:'('\n" +
" 4 0 H\n" +
" 4 1 S \"(\" Mixed:'('\n" +
" 5 0 H\n" +
" 5 3 S \"foo\" Mixed:name=ID\n" +
" 8 0 H\n" +
" 8 1 S \")\" Mixed:')'\n" +
" 9 0 H\n" +
" 9 1 S \")\" Mixed:')'\n" +
"10 0 H\n" +
"10 1 S \")\" Mixed:')'\n" +
" E Mixed'foo' Root\n" +
"11 0 H\n";
assertRegions(model,
expectation);
}
@Test
public void testAssignmentChildDelegate2() throws Exception {
String model = "6 (child(((foo))))\n".trim();
String expectation =
" 0 0 H\n" +
" B Mixed Root\n" +
" 0 1 S \"6\" Root:'6'\n" +
" 1 1 H \" \" Whitespace:TerminalRule'WS'\n" +
" 2 1 S \"(\" Mixed:'('\n" +
" 3 0 H\n" +
" 3 5 S \"child\" Mixed:'child'\n" +
" 8 0 H\n" +
" B Mixed'foo' Mixed:eobj=Mixed path:Mixed/eobj\n" +
" 8 1 S \"(\" Mixed:'('\n" +
" 9 0 H\n" +
" 9 1 S \"(\" Mixed:'('\n" +
"10 0 H\n" +
"10 1 S \"(\" Mixed:'('\n" +
"11 0 H\n" +
"11 3 S \"foo\" Mixed:name=ID\n" +
"14 0 H\n" +
"14 1 S \")\" Mixed:')'\n" +
"15 0 H\n" +
"15 1 S \")\" Mixed:')'\n" +
"16 0 H\n" +
"16 1 S \")\" Mixed:')'\n" +
" E Mixed'foo' Mixed:eobj=Mixed path:Mixed/eobj\n" +
"17 0 H\n" +
"17 1 S \")\" Mixed:')'\n" +
" E Mixed Root\n" +
"18 0 H\n";
assertRegions(model,
expectation);
}
@Test
public void testAssignedDatatype() throws Exception {
String model = "6 (datatype foo)\n".trim();
String expectation =
" 0 0 H\n" +
" B Mixed Root\n" +
" 0 1 S \"6\" Root:'6'\n" +
" 1 1 H \" \" Whitespace:TerminalRule'WS'\n" +
" 2 1 S \"(\" Mixed:'('\n" +
" 3 0 H\n" +
" 3 12 S \"datat...\" Mixed:datatype=Datatype\n" +
"15 0 H\n" +
"15 1 S \")\" Mixed:')'\n" +
" E Mixed Root\n" +
"16 0 H\n";
assertRegions(model,
expectation);
}
@Test
public void testAssignedDatatype2() throws Exception {
String model = "6 (datatype datatype foo)\n".trim();
String expectation =
" 0 0 H\n" +
" B Mixed Root\n" +
" 0 1 S \"6\" Root:'6'\n" +
" 1 1 H \" \" Whitespace:TerminalRule'WS'\n" +
" 2 1 S \"(\" Mixed:'('\n" +
" 3 0 H\n" +
" 3 21 S \"datat...\" Mixed:datatype=Datatype\n" +
"24 0 H\n" +
"24 1 S \")\" Mixed:')'\n" +
" E Mixed Root\n" +
"25 0 H\n";
assertRegions(model,
expectation);
}
@Test
public void testRef() throws Exception {
String model = "6 (foo) action (ref foo) end\n".trim();
String expectation =
" 0 0 H\n" +
" B AssignedAction Root\n" +
" 0 1 S \"6\" Root:'6'\n" +
" 1 1 H \" \" Whitespace:TerminalRule'WS'\n" +
" B Mixed'foo' Mixed:{AssignedAction.child=} path:AssignedAction/child\n" +
" 2 1 S \"(\" Mixed:'('\n" +
" 3 0 H\n" +
" 3 3 S \"foo\" Mixed:name=ID\n" +
" 6 0 H\n" +
" 6 1 S \")\" Mixed:')'\n" +
" E Mixed'foo' Mixed:{AssignedAction.child=} path:AssignedAction/child\n" +
" 7 1 H \" \" Whitespace:TerminalRule'WS'\n" +
" 8 6 S \"action\" Mixed:'action'\n" +
"14 1 H \" \" Whitespace:TerminalRule'WS'\n" +
" B Mixed Mixed:body=Mixed path:AssignedAction/body\n" +
"15 1 S \"(\" Mixed:'('\n" +
"16 0 H\n" +
"16 3 S \"ref\" Mixed:'ref'\n" +
"19 1 H \" \" Whitespace:TerminalRule'WS'\n" +
"20 3 S \"foo\" Mixed:ref=[Mixed|ID]\n" +
"23 0 H\n" +
"23 1 S \")\" Mixed:')'\n" +
" E Mixed Mixed:body=Mixed path:AssignedAction/body\n" +
"24 1 H \" \" Whitespace:TerminalRule'WS'\n" +
"25 3 S \"end\" Mixed:'end'\n" +
" E AssignedAction Root\n" +
"28 0 H\n";
assertRegions(model,
expectation);
}
@Test
public void testEnum() throws Exception {
String model = "6 (lit1)\n".trim();
String expectation =
"0 0 H\n" +
" B Mixed Root\n" +
"0 1 S \"6\" Root:'6'\n" +
"1 1 H \" \" Whitespace:TerminalRule'WS'\n" +
"2 1 S \"(\" Mixed:'('\n" +
"3 0 H\n" +
"3 4 S \"lit1\" Mixed:lit=Enum\n" +
"7 0 H\n" +
"7 1 S \")\" Mixed:')'\n" +
" E Mixed Root\n" +
"8 0 H\n";
assertRegions(model,
expectation);
}
@Test
public void testAssignmentAction() throws Exception {
String model = "6 (foo) action\n".trim();
String expectation =
" 0 0 H\n" +
" B AssignedAction Root\n" +
" 0 1 S \"6\" Root:'6'\n" +
" 1 1 H \" \" Whitespace:TerminalRule'WS'\n" +
" B Mixed'foo' Mixed:{AssignedAction.child=} path:AssignedAction/child\n" +
" 2 1 S \"(\" Mixed:'('\n" +
" 3 0 H\n" +
" 3 3 S \"foo\" Mixed:name=ID\n" +
" 6 0 H\n" +
" 6 1 S \")\" Mixed:')'\n" +
" E Mixed'foo' Mixed:{AssignedAction.child=} path:AssignedAction/child\n" +
" 7 1 H \" \" Whitespace:TerminalRule'WS'\n" +
" 8 6 S \"action\" Mixed:'action'\n" +
" E AssignedAction Root\n" +
"14 0 H\n";
assertRegions(model,
expectation);
}
@Test
public void testAssignmentActionAction() throws Exception {
String model = "6 (foo) action action\n".trim();
String expectation =
" 0 0 H\n" +
" B AssignedAction Root\n" +
" 0 1 S \"6\" Root:'6'\n" +
" 1 1 H \" \" Whitespace:TerminalRule'WS'\n" +
" B AssignedAction Mixed:{AssignedAction.child=} path:AssignedAction/child\n" +
" B Mixed'foo' Mixed:{AssignedAction.child=} path:AssignedAction/child=AssignedAction/child\n" +
" 2 1 S \"(\" Mixed:'('\n" +
" 3 0 H\n" +
" 3 3 S \"foo\" Mixed:name=ID\n" +
" 6 0 H\n" +
" 6 1 S \")\" Mixed:')'\n" +
" E Mixed'foo' Mixed:{AssignedAction.child=} path:AssignedAction/child=AssignedAction/child\n" +
" 7 1 H \" \" Whitespace:TerminalRule'WS'\n" +
" 8 6 S \"action\" Mixed:'action'\n" +
" E AssignedAction Mixed:{AssignedAction.child=} path:AssignedAction/child\n" +
"14 1 H \" \" Whitespace:TerminalRule'WS'\n" +
"15 6 S \"action\" Mixed:'action'\n" +
" E AssignedAction Root\n" +
"21 0 H\n";
assertRegions(model,
expectation);
}
@Test
public void testActionActionAction() throws Exception {
String model = "6 () action action\n".trim();
String expectation =
" 0 0 H\n" +
" B AssignedAction Root\n" +
" 0 1 S \"6\" Root:'6'\n" +
" 1 1 H \" \" Whitespace:TerminalRule'WS'\n" +
" B AssignedAction Mixed:{AssignedAction.child=} path:AssignedAction/child\n" +
" B Action Mixed:{AssignedAction.child=} path:AssignedAction/child=AssignedAction/child\n" +
" 2 1 S \"(\" Mixed:'('\n" +
" 3 0 H\n" +
" 3 1 S \")\" Mixed:')'\n" +
" E Action Mixed:{AssignedAction.child=} path:AssignedAction/child=AssignedAction/child\n" +
" 4 1 H \" \" Whitespace:TerminalRule'WS'\n" +
" 5 6 S \"action\" Mixed:'action'\n" +
" E AssignedAction Mixed:{AssignedAction.child=} path:AssignedAction/child\n" +
"11 1 H \" \" Whitespace:TerminalRule'WS'\n" +
"12 6 S \"action\" Mixed:'action'\n" +
" E AssignedAction Root\n" +
"18 0 H\n";
assertRegions(model,
expectation);
}
@Test
public void testFragmentID() throws Exception {
String model = "6 (fragment foo)\n".trim();
String expectation =
" 0 0 H\n" +
" B Action Root\n" +
" 0 1 S \"6\" Root:'6'\n" +
" 1 1 H \" \" Whitespace:TerminalRule'WS'\n" +
" 2 1 S \"(\" Mixed:'('\n" +
" 3 0 H\n" +
" 3 8 S \"fragment\" Mixed:'fragment'\n" +
"11 1 H \" \" Whitespace:TerminalRule'WS'\n" +
"12 3 S \"foo\" Fragment:fragName=ID\n" +
"15 0 H\n" +
"15 1 S \")\" Mixed:')'\n" +
" E Action Root\n" +
"16 0 H\n";
assertRegions(model,
expectation);
}
@Test
public void testFragmentRecursionID() throws Exception {
String model = "6 (fragment recursion foo)\n".trim();
String expectation =
" 0 0 H\n" +
" B Action Root\n" +
" 0 1 S \"6\" Root:'6'\n" +
" 1 1 H \" \" Whitespace:TerminalRule'WS'\n" +
" 2 1 S \"(\" Mixed:'('\n" +
" 3 0 H\n" +
" 3 8 S \"fragment\" Mixed:'fragment'\n" +
"11 1 H \" \" Whitespace:TerminalRule'WS'\n" +
"12 9 S \"recur...\" Fragment:'recursion'\n" +
"21 1 H \" \" Whitespace:TerminalRule'WS'\n" +
"22 3 S \"foo\" Fragment:fragName=ID\n" +
"25 0 H\n" +
"25 1 S \")\" Mixed:')'\n" +
" E Action Root\n" +
"26 0 H\n";
assertRegions(model,
expectation);
}
@Test
public void testFragmentChildAction() throws Exception {
String model = "6 (fragment child ())\n".trim();
String expectation =
" 0 0 H\n" +
" B Action Root\n" +
" 0 1 S \"6\" Root:'6'\n" +
" 1 1 H \" \" Whitespace:TerminalRule'WS'\n" +
" 2 1 S \"(\" Mixed:'('\n" +
" 3 0 H\n" +
" 3 8 S \"fragment\" Mixed:'fragment'\n" +
"11 1 H \" \" Whitespace:TerminalRule'WS'\n" +
"12 5 S \"child\" Fragment:'child'\n" +
"17 1 H \" \" Whitespace:TerminalRule'WS'\n" +
" B Action Fragment:mixed=Mixed path:Action/mixed\n" +
"18 1 S \"(\" Mixed:'('\n" +
"19 0 H\n" +
"19 1 S \")\" Mixed:')'\n" +
" E Action Fragment:mixed=Mixed path:Action/mixed\n" +
"20 0 H\n" +
"20 1 S \")\" Mixed:')'\n" +
" E Action Root\n" +
"21 0 H\n";
assertRegions(model,
expectation);
}
@Test
public void testFragmentChildID() throws Exception {
String model = "6 (fragment child (foo))\n".trim();
String expectation =
" 0 0 H\n" +
" B Action Root\n" +
" 0 1 S \"6\" Root:'6'\n" +
" 1 1 H \" \" Whitespace:TerminalRule'WS'\n" +
" 2 1 S \"(\" Mixed:'('\n" +
" 3 0 H\n" +
" 3 8 S \"fragment\" Mixed:'fragment'\n" +
"11 1 H \" \" Whitespace:TerminalRule'WS'\n" +
"12 5 S \"child\" Fragment:'child'\n" +
"17 1 H \" \" Whitespace:TerminalRule'WS'\n" +
" B Mixed'foo' Fragment:mixed=Mixed path:Action/mixed\n" +
"18 1 S \"(\" Mixed:'('\n" +
"19 0 H\n" +
"19 3 S \"foo\" Mixed:name=ID\n" +
"22 0 H\n" +
"22 1 S \")\" Mixed:')'\n" +
" E Mixed'foo' Fragment:mixed=Mixed path:Action/mixed\n" +
"23 0 H\n" +
"23 1 S \")\" Mixed:')'\n" +
" E Action Root\n" +
"24 0 H\n";
assertRegions(model,
expectation);
}
@Test
public void testFragmentRecursionChild() throws Exception {
String model = "6 (fragment recursion child ())\n".trim();
String expectation =
" 0 0 H\n" +
" B Action Root\n" +
" 0 1 S \"6\" Root:'6'\n" +
" 1 1 H \" \" Whitespace:TerminalRule'WS'\n" +
" 2 1 S \"(\" Mixed:'('\n" +
" 3 0 H\n" +
" 3 8 S \"fragment\" Mixed:'fragment'\n" +
"11 1 H \" \" Whitespace:TerminalRule'WS'\n" +
"12 9 S \"recur...\" Fragment:'recursion'\n" +
"21 1 H \" \" Whitespace:TerminalRule'WS'\n" +
"22 5 S \"child\" Fragment:'child'\n" +
"27 1 H \" \" Whitespace:TerminalRule'WS'\n" +
" B Action Fragment:mixed=Mixed path:Action/mixed\n" +
"28 1 S \"(\" Mixed:'('\n" +
"29 0 H\n" +
"29 1 S \")\" Mixed:')'\n" +
" E Action Fragment:mixed=Mixed path:Action/mixed\n" +
"30 0 H\n" +
"30 1 S \")\" Mixed:')'\n" +
" E Action Root\n" +
"31 0 H\n";
assertRegions(model,
expectation);
}
@Test
public void testMixedRootAction() throws Exception {
String model = "7 action (foo)\n".trim();
String expectation =
" 0 0 H\n" +
" B RootAction Root\n" +
" 0 1 S \"7\" Root:'7'\n" +
" 1 1 H \" \" Whitespace:TerminalRule'WS'\n" +
" 2 6 S \"action\" Root:'action'\n" +
" 8 1 H \" \" Whitespace:TerminalRule'WS'\n" +
" B Mixed'foo' Root:mixed=Mixed path:RootAction/mixed\n" +
" 9 1 S \"(\" Mixed:'('\n" +
"10 0 H\n" +
"10 3 S \"foo\" Mixed:name=ID\n" +
"13 0 H\n" +
"13 1 S \")\" Mixed:')'\n" +
" E Mixed'foo' Root:mixed=Mixed path:RootAction/mixed\n" +
" E RootAction Root\n" +
"14 0 H\n";
assertRegions(model,
expectation);
}
@Test
public void testComments1() throws Exception {
String model =
"/*xxxx*/\n" +
"8\n" +
"/*aaaaa*/\n" +
"c\n" +
"// last\n".trim();
String expectation =
" 0 H \"/*xxxx*/\" Comment:TerminalRule'ML_COMMENT' Association:NEXT\n" +
" 9 \"\\n" +
"\" Whitespace:TerminalRule'WS'\n" +
" B ValueList'[c]' Root\n" +
" 9 1 S \"8\" Root:'8'\n" +
"10 H \"\\n" +
"\" Whitespace:TerminalRule'WS'\n" +
" \"/*aaa...\" Comment:TerminalRule'ML_COMMENT' Association:NEXT\n" +
" 11 \"\\n" +
"\" Whitespace:TerminalRule'WS'\n" +
"21 1 S \"c\" ValueList:name+=ID\n" +
" E ValueList'[c]' Root\n" +
"22 H \"\\n" +
"\" Whitespace:TerminalRule'WS'\n" +
" 8 \"// last\" Comment:TerminalRule'SL_COMMENT' Association:CONTAINER\n";
assertRegions(model,
expectation);
}
private void assertRegions(CharSequence file, CharSequence expectation) throws Exception {
String exp = expectation.toString();
Root obj = parseHelper.parse(file);
validationTestHelper.assertNoErrors(obj);
ITextRegionAccess access1 = createFromNodeModel(obj);
ITextRegionAccess access2 = serializer.serializeToRegions(obj);
assertToStringDoesNotCrash(access1);
assertToStringDoesNotCrash(access2);
assertLinesAreConsistent(access1);
assertLinesAreConsistent(access2);
String tra1 = cfg(new TextRegionAccessToString().withRegionAccess(access1)) + "\n";
String tra2 = cfg(new TextRegionAccessToString().withRegionAccess(access2)) + "\n";
Assert.assertEquals(Strings.toPlatformLineSeparator(exp), Strings.toPlatformLineSeparator(tra1));
Assert.assertEquals(Strings.toPlatformLineSeparator(exp), Strings.toPlatformLineSeparator(tra2));
}
private void assertLinesAreConsistent(ITextRegionAccess access) {
Set<String> lines = Sets.newLinkedHashSet(Lists.transform(access.regionForDocument().getLineRegions(),
it -> it.getOffset() + ":" + it.getLength()));
String text = access.regionForDocument().getText();
for (int i = 0; i < text.length(); i++) {
ILineRegion line = access.regionForLineAtOffset(i);
String lineStr = line.getOffset() + ":" + line.getLength();
Assert.assertTrue(lines.contains(lineStr));
}
}
private void assertToStringDoesNotCrash(ITextRegionAccess access) {
ISequentialRegion current = access.regionForRootEObject().getPreviousHiddenRegion();
while (current != null) {
Assert.assertNotNull(current.toString());
if (current instanceof IHiddenRegion) {
current = ((IHiddenRegion) current).getNextSemanticRegion();
} else if (current instanceof ISemanticRegion) {
Assert.assertNotNull(((ISemanticRegion) current).getEObjectRegion().toString());
current = ((ISemanticRegion) current).getNextHiddenRegion();
}
}
}
private TextRegionAccessToString cfg(TextRegionAccessToString toStr) {
return toStr.hideColumnExplanation().withTextWidth(10);
}
private ITextRegionAccess createFromNodeModel(EObject obj) {
return textRegionAccessBuilder.get().forNodeModel((XtextResource) obj.eResource()).create();
}
}

View file

@ -1,759 +0,0 @@
/*******************************************************************************
* Copyright (c) 2014, 2017 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.formatting2.regionaccess.internal
import com.google.inject.Inject
import static extension org.eclipse.xtext.util.Strings.*
import static extension org.eclipse.xtext.tests.LineDelimiters.toUnix
import javax.inject.Provider
import org.eclipse.emf.ecore.EObject
import org.eclipse.xtext.formatting2.debug.TextRegionAccessToString
import org.eclipse.xtext.formatting2.regionaccess.TextRegionAccessBuilder
import org.eclipse.xtext.formatting2.regionaccess.internal.regionaccesstestlanguage.Root
import org.eclipse.xtext.formatting2.regionaccess.internal.tests.RegionAccessTestLanguageInjectorProvider
import org.eclipse.xtext.resource.XtextResource
import org.eclipse.xtext.serializer.impl.Serializer
import org.eclipse.xtext.testing.InjectWith
import org.eclipse.xtext.testing.XtextRunner
import org.eclipse.xtext.testing.util.ParseHelper
import org.eclipse.xtext.testing.validation.ValidationTestHelper
import org.junit.Assert
import org.junit.Test
import org.junit.runner.RunWith
import org.eclipse.xtext.formatting2.regionaccess.ITextRegionAccess
import org.eclipse.xtext.formatting2.regionaccess.IHiddenRegion
import org.eclipse.xtext.formatting2.regionaccess.ISequentialRegion
import org.eclipse.xtext.formatting2.regionaccess.ISemanticRegion
/**
* @author Moritz Eysholdt - Initial contribution and API
*/
@InjectWith(RegionAccessTestLanguageInjectorProvider)
@RunWith(XtextRunner)
class RegionAccessBuilderTest {
@Inject ParseHelper<Root> parseHelper
@Inject Provider<TextRegionAccessBuilder> textRegionAccessBuilder
@Inject ValidationTestHelper validationTestHelper
@Inject extension Serializer serializer
@Test def void testSimple() {
'''
1 foo
'''.toString.trim === '''
0 0 H
B Simple'foo' Root
0 1 S "1" Simple:'1'
1 1 H " " Whitespace:TerminalRule'WS'
2 3 S "foo" Simple:name=ID
E Simple'foo' Root
5 0 H
'''
}
@Test def void testMultiWhitespace1() {
'''
1 /**/ foo
'''.toString.trim === '''
0 0 H
B Simple'foo' Root
0 1 S "1" Simple:'1'
1 H " " Whitespace:TerminalRule'WS'
"/**/" Comment:TerminalRule'ML_COMMENT' Association:CONTAINER
6 " " Whitespace:TerminalRule'WS'
7 3 S "foo" Simple:name=ID
E Simple'foo' Root
10 0 H
'''
}
@Test def void testMultiWhitespace2() {
'''
1
/**/
foo
'''.toString.trim.toUnixLineSeparator === '''
0 0 H
B Simple'foo' Root
0 1 S "1" Simple:'1'
1 H "\n" Whitespace:TerminalRule'WS'
"/**/" Comment:TerminalRule'ML_COMMENT' Association:NEXT
6 "\n" Whitespace:TerminalRule'WS'
7 3 S "foo" Simple:name=ID
E Simple'foo' Root
10 0 H
'''
}
@Test def void testAssignedDelegate() {
'''
2 foo
'''.toString.trim === '''
0 0 H
B Delegation Root
0 1 S "2" Delegation:'2'
1 1 H " " Whitespace:TerminalRule'WS'
B Delegate'foo' Delegation:delegate=Delegate path:Delegation/delegate
2 3 S "foo" Delegate:name=ID
E Delegate'foo' Delegation:delegate=Delegate path:Delegation/delegate
E Delegation Root
5 0 H
'''
}
@Test def void testUnassignedDelegate() {
'''
3 foo
'''.toString.trim === '''
0 0 H
B Delegate'foo' Root
0 1 S "3" Unassigned:'3'
1 1 H " " Whitespace:TerminalRule'WS'
2 3 S "foo" Delegate:name=ID
E Delegate'foo' Root
5 0 H
'''
}
@Test def void testUnassignedPrefixedDelegate() {
'''
4 prefix foo
'''.toString.trim === '''
0 0 H
B PrefixedUnassigned Root
0 1 S "4" PrefixedUnassigned:'4'
1 1 H " " Whitespace:TerminalRule'WS'
B Delegate'foo' PrefixedUnassigned:delegate=PrefixedDelegate path:PrefixedUnassigned/delegate
2 6 S "prefix" PrefixedDelegate:'prefix'
8 1 H " " Whitespace:TerminalRule'WS'
9 3 S "foo" Delegate:name=ID
E Delegate'foo' PrefixedUnassigned:delegate=PrefixedDelegate path:PrefixedUnassigned/delegate
E PrefixedUnassigned Root
12 0 H
'''
}
@Test def void testExpression1() {
'''
5 a + b
'''.toString.trim === '''
0 0 H
B Add Root
0 1 S "5" Root:'5'
1 1 H " " Whitespace:TerminalRule'WS'
B Named'a' Expression:{Add.left=} path:Add/left
2 1 S "a" Primary:name=ID
E Named'a' Expression:{Add.left=} path:Add/left
3 1 H " " Whitespace:TerminalRule'WS'
4 1 S "+" Expression:'+'
5 1 H " " Whitespace:TerminalRule'WS'
B Named'b' Expression:right=Primary path:Add/right
6 1 S "b" Primary:name=ID
E Named'b' Expression:right=Primary path:Add/right
E Add Root
7 0 H
'''
}
@Test def void testExpression2() {
'''
5 (a + b) + c
'''.toString.trim === '''
0 0 H
B Add Root
0 1 S "5" Root:'5'
1 1 H " " Whitespace:TerminalRule'WS'
B Add Expression:{Add.left=} path:Add/left
2 1 S "(" Parenthesized:'('
3 0 H
B Named'a' Expression:{Add.left=} path:Add/left=Add/left
3 1 S "a" Primary:name=ID
E Named'a' Expression:{Add.left=} path:Add/left=Add/left
4 1 H " " Whitespace:TerminalRule'WS'
5 1 S "+" Expression:'+'
6 1 H " " Whitespace:TerminalRule'WS'
B Named'b' Expression:right=Primary path:Add/right=Add/left
7 1 S "b" Primary:name=ID
E Named'b' Expression:right=Primary path:Add/right=Add/left
8 0 H
8 1 S ")" Parenthesized:')'
E Add Expression:{Add.left=} path:Add/left
9 1 H " " Whitespace:TerminalRule'WS'
10 1 S "+" Expression:'+'
11 1 H " " Whitespace:TerminalRule'WS'
B Named'c' Expression:right=Primary path:Add/right
12 1 S "c" Primary:name=ID
E Named'c' Expression:right=Primary path:Add/right
E Add Root
13 0 H
'''
}
@Test def void testMixedUnassignedTerminal() {
'''
6 (unassigned foo)
'''.toString.trim === '''
0 0 H
B Action Root
0 1 S "6" Root:'6'
1 1 H " " Whitespace:TerminalRule'WS'
2 1 S "(" Mixed:'('
3 0 H
3 10 S "unass..." Mixed:'unassigned'
13 1 H " " Whitespace:TerminalRule'WS'
14 3 S "foo" Mixed:ID
17 0 H
17 1 S ")" Mixed:')'
E Action Root
18 0 H
'''
}
@Test def void testMixedUnassignedDatatype1() {
'''
6 (unassigned datatype foo)
'''.toString.trim === '''
0 0 H
B Action Root
0 1 S "6" Root:'6'
1 1 H " " Whitespace:TerminalRule'WS'
2 1 S "(" Mixed:'('
3 0 H
3 10 S "unass..." Mixed:'unassigned'
13 1 H " " Whitespace:TerminalRule'WS'
14 12 S "datat..." Mixed:Datatype
26 0 H
26 1 S ")" Mixed:')'
E Action Root
27 0 H
'''
}
@Test def void testMixedUnassignedDatatype2() {
'''
6 (unassigned datatype datatype foo)
'''.toString.trim === '''
0 0 H
B Action Root
0 1 S "6" Root:'6'
1 1 H " " Whitespace:TerminalRule'WS'
2 1 S "(" Mixed:'('
3 0 H
3 10 S "unass..." Mixed:'unassigned'
13 1 H " " Whitespace:TerminalRule'WS'
14 21 S "datat..." Mixed:Datatype
35 0 H
35 1 S ")" Mixed:')'
E Action Root
36 0 H
'''
}
@Test def void testAction() {
'''
6 ()
'''.toString.trim === '''
0 0 H
B Action Root
0 1 S "6" Root:'6'
1 1 H " " Whitespace:TerminalRule'WS'
2 1 S "(" Mixed:'('
3 0 H
3 1 S ")" Mixed:')'
E Action Root
4 0 H
'''
}
@Test def void testActionDelegate() {
'''
6 (())
'''.toString.trim === '''
0 0 H
B Action Root
0 1 S "6" Root:'6'
1 1 H " " Whitespace:TerminalRule'WS'
2 1 S "(" Mixed:'('
3 0 H
3 1 S "(" Mixed:'('
4 0 H
4 1 S ")" Mixed:')'
5 0 H
5 1 S ")" Mixed:')'
E Action Root
6 0 H
'''
}
@Test def void testActionDelegate2() {
'''
6 ((()))
'''.toString.trim === '''
0 0 H
B Action Root
0 1 S "6" Root:'6'
1 1 H " " Whitespace:TerminalRule'WS'
2 1 S "(" Mixed:'('
3 0 H
3 1 S "(" Mixed:'('
4 0 H
4 1 S "(" Mixed:'('
5 0 H
5 1 S ")" Mixed:')'
6 0 H
6 1 S ")" Mixed:')'
7 0 H
7 1 S ")" Mixed:')'
E Action Root
8 0 H
'''
}
@Test def void testAssignmentDelegate2() {
'''
6 (((foo)))
'''.toString.trim === '''
0 0 H
B Mixed'foo' Root
0 1 S "6" Root:'6'
1 1 H " " Whitespace:TerminalRule'WS'
2 1 S "(" Mixed:'('
3 0 H
3 1 S "(" Mixed:'('
4 0 H
4 1 S "(" Mixed:'('
5 0 H
5 3 S "foo" Mixed:name=ID
8 0 H
8 1 S ")" Mixed:')'
9 0 H
9 1 S ")" Mixed:')'
10 0 H
10 1 S ")" Mixed:')'
E Mixed'foo' Root
11 0 H
'''
}
@Test def void testAssignmentChildDelegate2() {
'''
6 (child(((foo))))
'''.toString.trim === '''
0 0 H
B Mixed Root
0 1 S "6" Root:'6'
1 1 H " " Whitespace:TerminalRule'WS'
2 1 S "(" Mixed:'('
3 0 H
3 5 S "child" Mixed:'child'
8 0 H
B Mixed'foo' Mixed:eobj=Mixed path:Mixed/eobj
8 1 S "(" Mixed:'('
9 0 H
9 1 S "(" Mixed:'('
10 0 H
10 1 S "(" Mixed:'('
11 0 H
11 3 S "foo" Mixed:name=ID
14 0 H
14 1 S ")" Mixed:')'
15 0 H
15 1 S ")" Mixed:')'
16 0 H
16 1 S ")" Mixed:')'
E Mixed'foo' Mixed:eobj=Mixed path:Mixed/eobj
17 0 H
17 1 S ")" Mixed:')'
E Mixed Root
18 0 H
'''
}
@Test def void testAssignedDatatype() {
'''
6 (datatype foo)
'''.toString.trim === '''
0 0 H
B Mixed Root
0 1 S "6" Root:'6'
1 1 H " " Whitespace:TerminalRule'WS'
2 1 S "(" Mixed:'('
3 0 H
3 12 S "datat..." Mixed:datatype=Datatype
15 0 H
15 1 S ")" Mixed:')'
E Mixed Root
16 0 H
'''
}
@Test def void testAssignedDatatype2() {
'''
6 (datatype datatype foo)
'''.toString.trim === '''
0 0 H
B Mixed Root
0 1 S "6" Root:'6'
1 1 H " " Whitespace:TerminalRule'WS'
2 1 S "(" Mixed:'('
3 0 H
3 21 S "datat..." Mixed:datatype=Datatype
24 0 H
24 1 S ")" Mixed:')'
E Mixed Root
25 0 H
'''
}
@Test def void testRef() {
'''
6 (foo) action (ref foo) end
'''.toString.trim === '''
0 0 H
B AssignedAction Root
0 1 S "6" Root:'6'
1 1 H " " Whitespace:TerminalRule'WS'
B Mixed'foo' Mixed:{AssignedAction.child=} path:AssignedAction/child
2 1 S "(" Mixed:'('
3 0 H
3 3 S "foo" Mixed:name=ID
6 0 H
6 1 S ")" Mixed:')'
E Mixed'foo' Mixed:{AssignedAction.child=} path:AssignedAction/child
7 1 H " " Whitespace:TerminalRule'WS'
8 6 S "action" Mixed:'action'
14 1 H " " Whitespace:TerminalRule'WS'
B Mixed Mixed:body=Mixed path:AssignedAction/body
15 1 S "(" Mixed:'('
16 0 H
16 3 S "ref" Mixed:'ref'
19 1 H " " Whitespace:TerminalRule'WS'
20 3 S "foo" Mixed:ref=[Mixed|ID]
23 0 H
23 1 S ")" Mixed:')'
E Mixed Mixed:body=Mixed path:AssignedAction/body
24 1 H " " Whitespace:TerminalRule'WS'
25 3 S "end" Mixed:'end'
E AssignedAction Root
28 0 H
'''
}
@Test def void testEnum() {
'''
6 (lit1)
'''.toString.trim === '''
0 0 H
B Mixed Root
0 1 S "6" Root:'6'
1 1 H " " Whitespace:TerminalRule'WS'
2 1 S "(" Mixed:'('
3 0 H
3 4 S "lit1" Mixed:lit=Enum
7 0 H
7 1 S ")" Mixed:')'
E Mixed Root
8 0 H
'''
}
@Test def void testAssignmentAction() {
'''
6 (foo) action
'''.toString.trim === '''
0 0 H
B AssignedAction Root
0 1 S "6" Root:'6'
1 1 H " " Whitespace:TerminalRule'WS'
B Mixed'foo' Mixed:{AssignedAction.child=} path:AssignedAction/child
2 1 S "(" Mixed:'('
3 0 H
3 3 S "foo" Mixed:name=ID
6 0 H
6 1 S ")" Mixed:')'
E Mixed'foo' Mixed:{AssignedAction.child=} path:AssignedAction/child
7 1 H " " Whitespace:TerminalRule'WS'
8 6 S "action" Mixed:'action'
E AssignedAction Root
14 0 H
'''
}
@Test def void testAssignmentActionAction() {
'''
6 (foo) action action
'''.toString.trim === '''
0 0 H
B AssignedAction Root
0 1 S "6" Root:'6'
1 1 H " " Whitespace:TerminalRule'WS'
B AssignedAction Mixed:{AssignedAction.child=} path:AssignedAction/child
B Mixed'foo' Mixed:{AssignedAction.child=} path:AssignedAction/child=AssignedAction/child
2 1 S "(" Mixed:'('
3 0 H
3 3 S "foo" Mixed:name=ID
6 0 H
6 1 S ")" Mixed:')'
E Mixed'foo' Mixed:{AssignedAction.child=} path:AssignedAction/child=AssignedAction/child
7 1 H " " Whitespace:TerminalRule'WS'
8 6 S "action" Mixed:'action'
E AssignedAction Mixed:{AssignedAction.child=} path:AssignedAction/child
14 1 H " " Whitespace:TerminalRule'WS'
15 6 S "action" Mixed:'action'
E AssignedAction Root
21 0 H
'''
}
@Test def void testActionActionAction() {
'''
6 () action action
'''.toString.trim === '''
0 0 H
B AssignedAction Root
0 1 S "6" Root:'6'
1 1 H " " Whitespace:TerminalRule'WS'
B AssignedAction Mixed:{AssignedAction.child=} path:AssignedAction/child
B Action Mixed:{AssignedAction.child=} path:AssignedAction/child=AssignedAction/child
2 1 S "(" Mixed:'('
3 0 H
3 1 S ")" Mixed:')'
E Action Mixed:{AssignedAction.child=} path:AssignedAction/child=AssignedAction/child
4 1 H " " Whitespace:TerminalRule'WS'
5 6 S "action" Mixed:'action'
E AssignedAction Mixed:{AssignedAction.child=} path:AssignedAction/child
11 1 H " " Whitespace:TerminalRule'WS'
12 6 S "action" Mixed:'action'
E AssignedAction Root
18 0 H
'''
}
@Test def void testFragmentID() {
'''
6 (fragment foo)
'''.toString.trim === '''
0 0 H
B Action Root
0 1 S "6" Root:'6'
1 1 H " " Whitespace:TerminalRule'WS'
2 1 S "(" Mixed:'('
3 0 H
3 8 S "fragment" Mixed:'fragment'
11 1 H " " Whitespace:TerminalRule'WS'
12 3 S "foo" Fragment:fragName=ID
15 0 H
15 1 S ")" Mixed:')'
E Action Root
16 0 H
'''
}
@Test def void testFragmentRecursionID() {
'''
6 (fragment recursion foo)
'''.toString.trim === '''
0 0 H
B Action Root
0 1 S "6" Root:'6'
1 1 H " " Whitespace:TerminalRule'WS'
2 1 S "(" Mixed:'('
3 0 H
3 8 S "fragment" Mixed:'fragment'
11 1 H " " Whitespace:TerminalRule'WS'
12 9 S "recur..." Fragment:'recursion'
21 1 H " " Whitespace:TerminalRule'WS'
22 3 S "foo" Fragment:fragName=ID
25 0 H
25 1 S ")" Mixed:')'
E Action Root
26 0 H
'''
}
@Test def void testFragmentChildAction() {
'''
6 (fragment child ())
'''.toString.trim === '''
0 0 H
B Action Root
0 1 S "6" Root:'6'
1 1 H " " Whitespace:TerminalRule'WS'
2 1 S "(" Mixed:'('
3 0 H
3 8 S "fragment" Mixed:'fragment'
11 1 H " " Whitespace:TerminalRule'WS'
12 5 S "child" Fragment:'child'
17 1 H " " Whitespace:TerminalRule'WS'
B Action Fragment:mixed=Mixed path:Action/mixed
18 1 S "(" Mixed:'('
19 0 H
19 1 S ")" Mixed:')'
E Action Fragment:mixed=Mixed path:Action/mixed
20 0 H
20 1 S ")" Mixed:')'
E Action Root
21 0 H
'''
}
@Test def void testFragmentChildID() {
'''
6 (fragment child (foo))
'''.toString.trim === '''
0 0 H
B Action Root
0 1 S "6" Root:'6'
1 1 H " " Whitespace:TerminalRule'WS'
2 1 S "(" Mixed:'('
3 0 H
3 8 S "fragment" Mixed:'fragment'
11 1 H " " Whitespace:TerminalRule'WS'
12 5 S "child" Fragment:'child'
17 1 H " " Whitespace:TerminalRule'WS'
B Mixed'foo' Fragment:mixed=Mixed path:Action/mixed
18 1 S "(" Mixed:'('
19 0 H
19 3 S "foo" Mixed:name=ID
22 0 H
22 1 S ")" Mixed:')'
E Mixed'foo' Fragment:mixed=Mixed path:Action/mixed
23 0 H
23 1 S ")" Mixed:')'
E Action Root
24 0 H
'''
}
@Test def void testFragmentRecursionChild() {
'''
6 (fragment recursion child ())
'''.toString.trim === '''
0 0 H
B Action Root
0 1 S "6" Root:'6'
1 1 H " " Whitespace:TerminalRule'WS'
2 1 S "(" Mixed:'('
3 0 H
3 8 S "fragment" Mixed:'fragment'
11 1 H " " Whitespace:TerminalRule'WS'
12 9 S "recur..." Fragment:'recursion'
21 1 H " " Whitespace:TerminalRule'WS'
22 5 S "child" Fragment:'child'
27 1 H " " Whitespace:TerminalRule'WS'
B Action Fragment:mixed=Mixed path:Action/mixed
28 1 S "(" Mixed:'('
29 0 H
29 1 S ")" Mixed:')'
E Action Fragment:mixed=Mixed path:Action/mixed
30 0 H
30 1 S ")" Mixed:')'
E Action Root
31 0 H
'''
}
@Test def void testMixedRootAction() {
'''
7 action (foo)
'''.toString.trim === '''
0 0 H
B RootAction Root
0 1 S "7" Root:'7'
1 1 H " " Whitespace:TerminalRule'WS'
2 6 S "action" Root:'action'
8 1 H " " Whitespace:TerminalRule'WS'
B Mixed'foo' Root:mixed=Mixed path:RootAction/mixed
9 1 S "(" Mixed:'('
10 0 H
10 3 S "foo" Mixed:name=ID
13 0 H
13 1 S ")" Mixed:')'
E Mixed'foo' Root:mixed=Mixed path:RootAction/mixed
E RootAction Root
14 0 H
'''
}
@Test def void testComments1() {
'''
/*xxxx*/
8
/*aaaaa*/
c
// last
'''.toString.toUnix.trim === '''
0 H "/*xxxx*/" Comment:TerminalRule'ML_COMMENT' Association:NEXT
9 "\n" Whitespace:TerminalRule'WS'
B ValueList'[c]' Root
9 1 S "8" Root:'8'
10 H "\n" Whitespace:TerminalRule'WS'
"/*aaa..." Comment:TerminalRule'ML_COMMENT' Association:NEXT
11 "\n" Whitespace:TerminalRule'WS'
21 1 S "c" ValueList:name+=ID
E ValueList'[c]' Root
22 H "\n" Whitespace:TerminalRule'WS'
8 "// last" Comment:TerminalRule'SL_COMMENT' Association:CONTAINER
'''
}
private def ===(CharSequence file, CharSequence expectation) {
val exp = expectation.toString
val obj = parseHelper.parse(file)
validationTestHelper.assertNoErrors(obj)
val access1 = obj.createFromNodeModel
val access2 = obj.serializeToRegions
assertToStringDoesNotCrash(access1)
assertToStringDoesNotCrash(access2)
assertLinesAreConsistent(access1)
assertLinesAreConsistent(access2)
val tra1 = new TextRegionAccessToString().withRegionAccess(access1).cfg() + "\n"
val tra2 = new TextRegionAccessToString().withRegionAccess(access2).cfg() + "\n"
Assert.assertEquals(exp.toPlatformLineSeparator, tra1.toPlatformLineSeparator)
Assert.assertEquals(exp.toPlatformLineSeparator, tra2.toPlatformLineSeparator)
}
private def assertLinesAreConsistent(ITextRegionAccess access) {
val lines = access.regionForDocument.lineRegions.map[offset +":" + length].toSet
val text = access.regionForDocument.text
for(var i = 0; i < text.length; i++) {
val line = access.regionForLineAtOffset(i)
val lineStr = line.offset + ":" + line.length
Assert.assertTrue(lines.contains(lineStr))
}
}
private def assertToStringDoesNotCrash(ITextRegionAccess access) {
var current = access.regionForRootEObject.previousHiddenRegion as ISequentialRegion
while (current !== null) {
Assert.assertNotNull(current.toString)
switch current {
IHiddenRegion: {
current = current.nextSemanticRegion
}
ISemanticRegion: {
Assert.assertNotNull(current.EObjectRegion.toString)
current = current.nextHiddenRegion
}
}
}
}
private def TextRegionAccessToString cfg(TextRegionAccessToString toStr) {
toStr.hideColumnExplanation().withTextWidth(10)
}
private def createFromNodeModel(EObject obj) {
textRegionAccessBuilder.get.forNodeModel(obj.eResource as XtextResource).create
}
}

View file

@ -0,0 +1,341 @@
/**
* Copyright (c) 2017, 2021 TypeFox GmbH (http://www.typefox.io) 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.formatting2.regionaccess.internal;
import java.util.List;
import org.eclipse.xtext.formatting2.regionaccess.ISemanticRegion;
import org.eclipse.xtext.formatting2.regionaccess.ITextRegionAccess;
import org.eclipse.xtext.formatting2.regionaccess.ITextRegionDiffBuilder;
import org.eclipse.xtext.formatting2.regionaccess.internal.regionaccesstestlanguage.RegionaccesstestlanguagePackage;
import org.eclipse.xtext.formatting2.regionaccess.internal.tests.RegionAccessTestLanguageInjectorProvider;
import org.eclipse.xtext.testing.InjectWith;
import org.eclipse.xtext.testing.XtextRunner;
import org.junit.Test;
import org.junit.runner.RunWith;
import com.google.common.collect.Iterables;
import com.google.inject.Inject;
/**
* @author Moritz Eysholdt - Initial contribution and API
*/
@InjectWith(RegionAccessTestLanguageInjectorProvider.class)
@RunWith(XtextRunner.class)
public class RegionAccessCommentsTest {
@Inject
private RegionAccessTestHelper regionAccessTestHelper;
@Test
public void testDeleteFirstRegion1() throws Exception {
String model =
"/*h*/\n" +
"\n" +
"/*8*/\n" +
"8 //8\n" +
"/*a*/\n" +
"a\n";
ITextRegionAccess access = regionAccessTestHelper.toTextRegionAccess(model);
ITextRegionAccess modifiedAccess = regionAccessTestHelper.modify(access, (ITextRegionDiffBuilder it) -> {
ISemanticRegion foo = access.regionForRootEObject().getAllRegionsFor().keyword("8");
it.remove(foo);
});
String expectation =
" 0 1 H \"/*h*/\" Comment:TerminalRule'ML_COMMENT' Association:CONTAINER\n" +
" \"\\n" +
"\\n" +
"\" Whitespace:TerminalRule'WS'\n" +
" \"/*a*/\" Comment:TerminalRule'ML_COMMENT' Association:NEXT\n" +
" 13 \"\\n" +
"\" Whitespace:TerminalRule'WS'\n" +
" B ValueList'[a]' Root\n" +
"13 1 S \"a\" ValueList:name+=ID\n" +
" E ValueList'[a]' Root\n" +
"14 0 H\n" +
"------------ diff 1 ------------\n" +
" 0 H \"/*h*/\" Comment:TerminalRule'ML_COMMENT' Association:CONTAINER\n" +
" \"\\n" +
"\\n" +
"\" Whitespace:TerminalRule'WS'\n" +
" \"/*8*/\" Comment:TerminalRule'ML_COMMENT' Association:NEXT\n" +
" 13 \"\\n" +
"\" Whitespace:TerminalRule'WS'\n" +
"13 1 S \"8\" Root:'8'\n" +
"14 H \" \" Whitespace:TerminalRule'WS'\n" +
" \"//8\\n" +
"\" Comment:TerminalRule'SL_COMMENT' Association:PREVIOUS\n" +
" \"/*a*/\" Comment:TerminalRule'ML_COMMENT' Association:NEXT\n" +
" 11 \"\\n" +
"\" Whitespace:TerminalRule'WS'\n";
regionAccessTestHelper.assertRegions(modifiedAccess, expectation);
}
@Test
public void testDeleteFirstRegion2() throws Exception {
String model =
"/*h*/\n" +
"\n" +
"/*81*/\n" +
"/*82*/\n" +
"8 //8\n" +
"/*a*/\n" +
"a\n";
ITextRegionAccess access = regionAccessTestHelper.toTextRegionAccess(model);
ITextRegionAccess modifiedAccess = regionAccessTestHelper.modify(access, (ITextRegionDiffBuilder it) -> {
ISemanticRegion foo = access.regionForRootEObject().getAllRegionsFor().keyword("8");
it.remove(foo);
});
String expectation =
" 0 1 H \"/*h*/\" Comment:TerminalRule'ML_COMMENT' Association:CONTAINER\n" +
" \"\\n" +
"\\n" +
"\" Whitespace:TerminalRule'WS'\n" +
" \"/*a*/\" Comment:TerminalRule'ML_COMMENT' Association:NEXT\n" +
" 13 \"\\n" +
"\" Whitespace:TerminalRule'WS'\n" +
" B ValueList'[a]' Root\n" +
"13 1 S \"a\" ValueList:name+=ID\n" +
" E ValueList'[a]' Root\n" +
"14 0 H\n" +
"------------ diff 1 ------------\n" +
" 0 H \"/*h*/\" Comment:TerminalRule'ML_COMMENT' Association:CONTAINER\n" +
" \"\\n" +
"\\n" +
"\" Whitespace:TerminalRule'WS'\n" +
" \"/*81*/\" Comment:TerminalRule'ML_COMMENT' Association:NEXT\n" +
" \"\\n" +
"\" Whitespace:TerminalRule'WS'\n" +
" \"/*82*/\" Comment:TerminalRule'ML_COMMENT' Association:NEXT\n" +
" 21 \"\\n" +
"\" Whitespace:TerminalRule'WS'\n" +
"21 1 S \"8\" Root:'8'\n" +
"22 H \" \" Whitespace:TerminalRule'WS'\n" +
" \"//8\\n" +
"\" Comment:TerminalRule'SL_COMMENT' Association:PREVIOUS\n" +
" \"/*a*/\" Comment:TerminalRule'ML_COMMENT' Association:NEXT\n" +
" 11 \"\\n" +
"\" Whitespace:TerminalRule'WS'\n";
regionAccessTestHelper.assertRegions(modifiedAccess, expectation);
}
@Test
public void testDeleteFirstRegion3() throws Exception {
String model =
"/*h*/\n" +
"/*81*/\n" +
"\n" +
"/*82*/\n" +
"8 //8\n" +
"/*a*/\n" +
"a\n";
ITextRegionAccess access = regionAccessTestHelper.toTextRegionAccess(model);
ITextRegionAccess modifiedAccess = regionAccessTestHelper.modify(access, (ITextRegionDiffBuilder it) -> {
ISemanticRegion foo = access.regionForRootEObject().getAllRegionsFor().keyword("8");
it.remove(foo);
});
String expectation =
" 0 1 H \"/*h*/\" Comment:TerminalRule'ML_COMMENT' Association:CONTAINER\n" +
" \"\\n" +
"\" Whitespace:TerminalRule'WS'\n" +
" \"/*81*/\" Comment:TerminalRule'ML_COMMENT' Association:CONTAINER\n" +
" \"\\n" +
"\\n" +
"\" Whitespace:TerminalRule'WS'\n" +
" \"/*a*/\" Comment:TerminalRule'ML_COMMENT' Association:NEXT\n" +
" 20 \"\\n" +
"\" Whitespace:TerminalRule'WS'\n" +
" B ValueList'[a]' Root\n" +
"20 1 S \"a\" ValueList:name+=ID\n" +
" E ValueList'[a]' Root\n" +
"21 0 H\n" +
"------------ diff 1 ------------\n" +
" 0 H \"/*h*/\" Comment:TerminalRule'ML_COMMENT' Association:CONTAINER\n" +
" \"\\n" +
"\" Whitespace:TerminalRule'WS'\n" +
" \"/*81*/\" Comment:TerminalRule'ML_COMMENT' Association:CONTAINER\n" +
" \"\\n" +
"\\n" +
"\" Whitespace:TerminalRule'WS'\n" +
" \"/*82*/\" Comment:TerminalRule'ML_COMMENT' Association:NEXT\n" +
" 21 \"\\n" +
"\" Whitespace:TerminalRule'WS'\n" +
"21 1 S \"8\" Root:'8'\n" +
"22 H \" \" Whitespace:TerminalRule'WS'\n" +
" \"//8\\n" +
"\" Comment:TerminalRule'SL_COMMENT' Association:PREVIOUS\n" +
" \"/*a*/\" Comment:TerminalRule'ML_COMMENT' Association:NEXT\n" +
" 11 \"\\n" +
"\" Whitespace:TerminalRule'WS'\n";
regionAccessTestHelper.assertRegions(modifiedAccess, expectation);
}
@Test
public void testDeleteFirstRegion4() throws Exception {
String model =
"/*h*/\n" +
"/*81*/\n" +
"/*82*/\n" +
"\n" +
"8 //8\n" +
"/*a*/\n" +
"a\n";
ITextRegionAccess access = regionAccessTestHelper.toTextRegionAccess(model);
ITextRegionAccess modifiedAccess = regionAccessTestHelper.modify(access, (ITextRegionDiffBuilder it) -> {
ISemanticRegion foo = access.regionForRootEObject().getAllRegionsFor().keyword("8");
it.remove(foo);
});
String expectation =
" 0 1 H \"/*h*/\" Comment:TerminalRule'ML_COMMENT' Association:CONTAINER\n" +
" \"\\n" +
"\" Whitespace:TerminalRule'WS'\n" +
" \"/*81*/\" Comment:TerminalRule'ML_COMMENT' Association:CONTAINER\n" +
" \"\\n" +
"\" Whitespace:TerminalRule'WS'\n" +
" \"/*82*/\" Comment:TerminalRule'ML_COMMENT' Association:CONTAINER\n" +
" \"\\n" +
"\\n" +
"\" Whitespace:TerminalRule'WS'\n" +
" \"/*a*/\" Comment:TerminalRule'ML_COMMENT' Association:NEXT\n" +
" 27 \"\\n" +
"\" Whitespace:TerminalRule'WS'\n" +
" B ValueList'[a]' Root\n" +
"27 1 S \"a\" ValueList:name+=ID\n" +
" E ValueList'[a]' Root\n" +
"28 0 H\n" +
"------------ diff 1 ------------\n" +
" 0 H \"/*h*/\" Comment:TerminalRule'ML_COMMENT' Association:CONTAINER\n" +
" \"\\n" +
"\" Whitespace:TerminalRule'WS'\n" +
" \"/*81*/\" Comment:TerminalRule'ML_COMMENT' Association:CONTAINER\n" +
" \"\\n" +
"\" Whitespace:TerminalRule'WS'\n" +
" \"/*82*/\" Comment:TerminalRule'ML_COMMENT' Association:CONTAINER\n" +
" 21 \"\\n" +
"\\n" +
"\" Whitespace:TerminalRule'WS'\n" +
"21 1 S \"8\" Root:'8'\n" +
"22 H \" \" Whitespace:TerminalRule'WS'\n" +
" \"//8\\n" +
"\" Comment:TerminalRule'SL_COMMENT' Association:PREVIOUS\n" +
" \"/*a*/\" Comment:TerminalRule'ML_COMMENT' Association:NEXT\n" +
" 11 \"\\n" +
"\" Whitespace:TerminalRule'WS'\n";
regionAccessTestHelper.assertRegions(modifiedAccess, expectation);
}
@Test
public void testDeleteMiddleRegion() throws Exception {
String model =
"8\n" +
"a /*a*/ //a\n" +
"/*b1*/\n" +
"/*b2*/\n" +
"b\n";
ITextRegionAccess access = regionAccessTestHelper.toTextRegionAccess(model);
ITextRegionAccess modifiedAccess = regionAccessTestHelper.modify(access, (ITextRegionDiffBuilder it) -> {
ISemanticRegion foo = Iterables.getFirst(access.regionForRootEObject().getAllRegionsFor()
.features(RegionaccesstestlanguagePackage.Literals.VALUE_LIST__NAME), null);
it.remove(foo);
});
String expectation =
" 0 0 H\n" +
" B ValueList'[a, b]' Root\n" +
" 0 1 S \"8\" Root:'8'\n" +
" 1 1 H \"\\n" +
"\" Whitespace:TerminalRule'WS'\n" +
" \"/*b1*/\" Comment:TerminalRule'ML_COMMENT' Association:NEXT\n" +
" \"\\n" +
"\" Whitespace:TerminalRule'WS'\n" +
" \"/*b2*/\" Comment:TerminalRule'ML_COMMENT' Association:NEXT\n" +
" 15 \"\\n" +
"\" Whitespace:TerminalRule'WS'\n" +
"16 1 S \"b\" ValueList:name+=ID\n" +
" E ValueList'[a, b]' Root\n" +
"17 0 H\n" +
"------------ diff 1 ------------\n" +
" 1 1 H \"\\n" +
"\" Whitespace:TerminalRule'WS'\n" +
" 2 1 S \"a\" ValueList:name+=ID\n" +
" 3 H \" \" Whitespace:TerminalRule'WS'\n" +
" \"/*a*/\" Comment:TerminalRule'ML_COMMENT' Association:PREVIOUS\n" +
" \" \" Whitespace:TerminalRule'WS'\n" +
" \"//a\\n" +
"\" Comment:TerminalRule'SL_COMMENT' Association:PREVIOUS\n" +
" \"/*b1*/\" Comment:TerminalRule'ML_COMMENT' Association:NEXT\n" +
" \"\\n" +
"\" Whitespace:TerminalRule'WS'\n" +
" \"/*b2*/\" Comment:TerminalRule'ML_COMMENT' Association:NEXT\n" +
" 25 \"\\n" +
"\" Whitespace:TerminalRule'WS'\n";
regionAccessTestHelper.assertRegions(modifiedAccess, expectation);
}
@Test
public void testMove() throws Exception {
String model =
"8//8\n" +
"/*a*/\n" +
"a//a\n" +
"/*b*/\n" +
"b//b\n" +
"/*c*/\n" +
"c\n";
ITextRegionAccess access = regionAccessTestHelper.toTextRegionAccess(model);
ITextRegionAccess modifiedAccess = regionAccessTestHelper.modify(access, (ITextRegionDiffBuilder it) -> {
List<ISemanticRegion> regions = access.regionForRootEObject().getAllRegionsFor()
.features(RegionaccesstestlanguagePackage.Literals.VALUE_LIST__NAME);
ISemanticRegion a = regions.get(0);
ISemanticRegion b = regions.get(1);
it.move(b.getNextHiddenRegion(), a.getPreviousHiddenRegion(), a.getNextHiddenRegion());
});
String expectation =
" 0 0 H\n" +
" B ValueList'[a, b, c]' Root\n" +
" 0 1 S \"8\" Root:'8'\n" +
" 1 1 H \"//8\\n" +
"\" Comment:TerminalRule'SL_COMMENT' Association:PREVIOUS\n" +
" \"/*b*/\" Comment:TerminalRule'ML_COMMENT' Association:NEXT\n" +
" 10 \"\\n" +
"\" Whitespace:TerminalRule'WS'\n" +
"11 1 S \"b\" ValueList:name+=ID\n" +
"12 2 H \"//b\\n" +
"\" Comment:TerminalRule'SL_COMMENT' Association:PREVIOUS\n" +
" \"/*a*/\" Comment:TerminalRule'ML_COMMENT' Association:NEXT\n" +
" 10 \"\\n" +
"\" Whitespace:TerminalRule'WS'\n" +
"22 1 2 S \"a\" ValueList:name+=ID\n" +
"23 2 H \"//a\\n" +
"\" Comment:TerminalRule'SL_COMMENT' Association:PREVIOUS\n" +
" \"/*c*/\" Comment:TerminalRule'ML_COMMENT' Association:NEXT\n" +
" 10 \"\\n" +
"\" Whitespace:TerminalRule'WS'\n" +
"33 1 S \"c\" ValueList:name+=ID\n" +
" E ValueList'[a, b, c]' Root\n" +
"34 0 H\n" +
"------------ diff 1 ------------\n" +
" 1 H \"//8\\n" +
"\" Comment:TerminalRule'SL_COMMENT' Association:PREVIOUS\n" +
" \"/*a*/\" Comment:TerminalRule'ML_COMMENT' Association:NEXT\n" +
" 10 \"\\n" +
"\" Whitespace:TerminalRule'WS'\n" +
"11 1 S \"a\" ValueList:name+=ID\n" +
"12 H \"//a\\n" +
"\" Comment:TerminalRule'SL_COMMENT' Association:PREVIOUS\n" +
" \"/*b*/\" Comment:TerminalRule'ML_COMMENT' Association:NEXT\n" +
" 10 \"\\n" +
"\" Whitespace:TerminalRule'WS'\n" +
"------------ diff 2 ------------\n" +
"23 H \"//b\\n" +
"\" Comment:TerminalRule'SL_COMMENT' Association:PREVIOUS\n" +
" \"/*c*/\" Comment:TerminalRule'ML_COMMENT' Association:NEXT\n" +
" 10 \"\\n" +
"\" Whitespace:TerminalRule'WS'\n";
regionAccessTestHelper.assertRegions(modifiedAccess, expectation);
}
}

View file

@ -1,263 +0,0 @@
/*******************************************************************************
* Copyright (c) 2017, 2020 TypeFox GmbH (http://www.typefox.io) 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.formatting2.regionaccess.internal
import com.google.inject.Inject
import org.eclipse.xtext.formatting2.regionaccess.internal.regionaccesstestlanguage.RegionaccesstestlanguagePackage
import org.eclipse.xtext.formatting2.regionaccess.internal.tests.RegionAccessTestLanguageInjectorProvider
import org.eclipse.xtext.testing.InjectWith
import org.eclipse.xtext.testing.XtextRunner
import org.junit.Test
import org.junit.runner.RunWith
/**
* @author Moritz Eysholdt - Initial contribution and API
*/
@InjectWith(RegionAccessTestLanguageInjectorProvider)
@RunWith(XtextRunner)
class RegionAccessCommentsTest {
@Inject extension RegionAccessTestHelper
@Test def void testDeleteFirstRegion1() throws Exception {
val access = '''
/*h*/
/*8*/
8 //8
/*a*/
a
'''.toTextRegionAccess
access.modify [
val foo = access.regionForRootEObject.allRegionsFor.keyword("8")
remove(foo)
] === '''
0 1 H "/*h*/" Comment:TerminalRule'ML_COMMENT' Association:CONTAINER
"\n\n" Whitespace:TerminalRule'WS'
"/*a*/" Comment:TerminalRule'ML_COMMENT' Association:NEXT
13 "\n" Whitespace:TerminalRule'WS'
B ValueList'[a]' Root
13 1 S "a" ValueList:name+=ID
E ValueList'[a]' Root
14 0 H
------------ diff 1 ------------
0 H "/*h*/" Comment:TerminalRule'ML_COMMENT' Association:CONTAINER
"\n\n" Whitespace:TerminalRule'WS'
"/*8*/" Comment:TerminalRule'ML_COMMENT' Association:NEXT
13 "\n" Whitespace:TerminalRule'WS'
13 1 S "8" Root:'8'
14 H " " Whitespace:TerminalRule'WS'
"//8\n" Comment:TerminalRule'SL_COMMENT' Association:PREVIOUS
"/*a*/" Comment:TerminalRule'ML_COMMENT' Association:NEXT
11 "\n" Whitespace:TerminalRule'WS'
'''
}
@Test def void testDeleteFirstRegion2() throws Exception {
val access = '''
/*h*/
/*81*/
/*82*/
8 //8
/*a*/
a
'''.toTextRegionAccess
access.modify [
val foo = access.regionForRootEObject.allRegionsFor.keyword("8")
remove(foo)
] === '''
0 1 H "/*h*/" Comment:TerminalRule'ML_COMMENT' Association:CONTAINER
"\n\n" Whitespace:TerminalRule'WS'
"/*a*/" Comment:TerminalRule'ML_COMMENT' Association:NEXT
13 "\n" Whitespace:TerminalRule'WS'
B ValueList'[a]' Root
13 1 S "a" ValueList:name+=ID
E ValueList'[a]' Root
14 0 H
------------ diff 1 ------------
0 H "/*h*/" Comment:TerminalRule'ML_COMMENT' Association:CONTAINER
"\n\n" Whitespace:TerminalRule'WS'
"/*81*/" Comment:TerminalRule'ML_COMMENT' Association:NEXT
"\n" Whitespace:TerminalRule'WS'
"/*82*/" Comment:TerminalRule'ML_COMMENT' Association:NEXT
21 "\n" Whitespace:TerminalRule'WS'
21 1 S "8" Root:'8'
22 H " " Whitespace:TerminalRule'WS'
"//8\n" Comment:TerminalRule'SL_COMMENT' Association:PREVIOUS
"/*a*/" Comment:TerminalRule'ML_COMMENT' Association:NEXT
11 "\n" Whitespace:TerminalRule'WS'
'''
}
@Test def void testDeleteFirstRegion3() throws Exception {
val access = '''
/*h*/
/*81*/
/*82*/
8 //8
/*a*/
a
'''.toTextRegionAccess
access.modify [
val foo = access.regionForRootEObject.allRegionsFor.keyword("8")
remove(foo)
] === '''
0 1 H "/*h*/" Comment:TerminalRule'ML_COMMENT' Association:CONTAINER
"\n" Whitespace:TerminalRule'WS'
"/*81*/" Comment:TerminalRule'ML_COMMENT' Association:CONTAINER
"\n\n" Whitespace:TerminalRule'WS'
"/*a*/" Comment:TerminalRule'ML_COMMENT' Association:NEXT
20 "\n" Whitespace:TerminalRule'WS'
B ValueList'[a]' Root
20 1 S "a" ValueList:name+=ID
E ValueList'[a]' Root
21 0 H
------------ diff 1 ------------
0 H "/*h*/" Comment:TerminalRule'ML_COMMENT' Association:CONTAINER
"\n" Whitespace:TerminalRule'WS'
"/*81*/" Comment:TerminalRule'ML_COMMENT' Association:CONTAINER
"\n\n" Whitespace:TerminalRule'WS'
"/*82*/" Comment:TerminalRule'ML_COMMENT' Association:NEXT
21 "\n" Whitespace:TerminalRule'WS'
21 1 S "8" Root:'8'
22 H " " Whitespace:TerminalRule'WS'
"//8\n" Comment:TerminalRule'SL_COMMENT' Association:PREVIOUS
"/*a*/" Comment:TerminalRule'ML_COMMENT' Association:NEXT
11 "\n" Whitespace:TerminalRule'WS'
'''
}
@Test def void testDeleteFirstRegion4() throws Exception {
val access = '''
/*h*/
/*81*/
/*82*/
8 //8
/*a*/
a
'''.toTextRegionAccess
access.modify [
val foo = access.regionForRootEObject.allRegionsFor.keyword("8")
remove(foo)
] === '''
0 1 H "/*h*/" Comment:TerminalRule'ML_COMMENT' Association:CONTAINER
"\n" Whitespace:TerminalRule'WS'
"/*81*/" Comment:TerminalRule'ML_COMMENT' Association:CONTAINER
"\n" Whitespace:TerminalRule'WS'
"/*82*/" Comment:TerminalRule'ML_COMMENT' Association:CONTAINER
"\n\n" Whitespace:TerminalRule'WS'
"/*a*/" Comment:TerminalRule'ML_COMMENT' Association:NEXT
27 "\n" Whitespace:TerminalRule'WS'
B ValueList'[a]' Root
27 1 S "a" ValueList:name+=ID
E ValueList'[a]' Root
28 0 H
------------ diff 1 ------------
0 H "/*h*/" Comment:TerminalRule'ML_COMMENT' Association:CONTAINER
"\n" Whitespace:TerminalRule'WS'
"/*81*/" Comment:TerminalRule'ML_COMMENT' Association:CONTAINER
"\n" Whitespace:TerminalRule'WS'
"/*82*/" Comment:TerminalRule'ML_COMMENT' Association:CONTAINER
21 "\n\n" Whitespace:TerminalRule'WS'
21 1 S "8" Root:'8'
22 H " " Whitespace:TerminalRule'WS'
"//8\n" Comment:TerminalRule'SL_COMMENT' Association:PREVIOUS
"/*a*/" Comment:TerminalRule'ML_COMMENT' Association:NEXT
11 "\n" Whitespace:TerminalRule'WS'
'''
}
@Test def void testDeleteMiddleRegion() throws Exception {
val access = '''
8
a /*a*/ //a
/*b1*/
/*b2*/
b
'''.toTextRegionAccess
access.modify [
val foo = access.regionForRootEObject.allRegionsFor.features(RegionaccesstestlanguagePackage.Literals.VALUE_LIST__NAME).head
remove(foo)
] === '''
0 0 H
B ValueList'[a, b]' Root
0 1 S "8" Root:'8'
1 1 H "\n" Whitespace:TerminalRule'WS'
"/*b1*/" Comment:TerminalRule'ML_COMMENT' Association:NEXT
"\n" Whitespace:TerminalRule'WS'
"/*b2*/" Comment:TerminalRule'ML_COMMENT' Association:NEXT
15 "\n" Whitespace:TerminalRule'WS'
16 1 S "b" ValueList:name+=ID
E ValueList'[a, b]' Root
17 0 H
------------ diff 1 ------------
1 1 H "\n" Whitespace:TerminalRule'WS'
2 1 S "a" ValueList:name+=ID
3 H " " Whitespace:TerminalRule'WS'
"/*a*/" Comment:TerminalRule'ML_COMMENT' Association:PREVIOUS
" " Whitespace:TerminalRule'WS'
"//a\n" Comment:TerminalRule'SL_COMMENT' Association:PREVIOUS
"/*b1*/" Comment:TerminalRule'ML_COMMENT' Association:NEXT
"\n" Whitespace:TerminalRule'WS'
"/*b2*/" Comment:TerminalRule'ML_COMMENT' Association:NEXT
25 "\n" Whitespace:TerminalRule'WS'
'''
}
@Test def void testMove() throws Exception {
val access = '''
8//8
/*a*/
a//a
/*b*/
b//b
/*c*/
c
'''.toTextRegionAccess
access.modify [
val regions = access.regionForRootEObject.allRegionsFor.features(RegionaccesstestlanguagePackage.Literals.VALUE_LIST__NAME)
val a = regions.get(0)
val b = regions.get(1)
move(b.nextHiddenRegion, a.previousHiddenRegion, a.nextHiddenRegion)
] === '''
0 0 H
B ValueList'[a, b, c]' Root
0 1 S "8" Root:'8'
1 1 H "//8\n" Comment:TerminalRule'SL_COMMENT' Association:PREVIOUS
"/*b*/" Comment:TerminalRule'ML_COMMENT' Association:NEXT
10 "\n" Whitespace:TerminalRule'WS'
11 1 S "b" ValueList:name+=ID
12 2 H "//b\n" Comment:TerminalRule'SL_COMMENT' Association:PREVIOUS
"/*a*/" Comment:TerminalRule'ML_COMMENT' Association:NEXT
10 "\n" Whitespace:TerminalRule'WS'
22 1 2 S "a" ValueList:name+=ID
23 2 H "//a\n" Comment:TerminalRule'SL_COMMENT' Association:PREVIOUS
"/*c*/" Comment:TerminalRule'ML_COMMENT' Association:NEXT
10 "\n" Whitespace:TerminalRule'WS'
33 1 S "c" ValueList:name+=ID
E ValueList'[a, b, c]' Root
34 0 H
------------ diff 1 ------------
1 H "//8\n" Comment:TerminalRule'SL_COMMENT' Association:PREVIOUS
"/*a*/" Comment:TerminalRule'ML_COMMENT' Association:NEXT
10 "\n" Whitespace:TerminalRule'WS'
11 1 S "a" ValueList:name+=ID
12 H "//a\n" Comment:TerminalRule'SL_COMMENT' Association:PREVIOUS
"/*b*/" Comment:TerminalRule'ML_COMMENT' Association:NEXT
10 "\n" Whitespace:TerminalRule'WS'
------------ diff 2 ------------
23 H "//b\n" Comment:TerminalRule'SL_COMMENT' Association:PREVIOUS
"/*c*/" Comment:TerminalRule'ML_COMMENT' Association:NEXT
10 "\n" Whitespace:TerminalRule'WS'
'''
}
}

View file

@ -0,0 +1,336 @@
/**
* Copyright (c) 2017, 2021 TypeFox GmbH (http://www.typefox.io) 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.formatting2.regionaccess.internal;
import java.util.List;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.xtext.formatting2.regionaccess.IEObjectRegion;
import org.eclipse.xtext.formatting2.regionaccess.ISemanticRegion;
import org.eclipse.xtext.formatting2.regionaccess.ITextRegionAccess;
import org.eclipse.xtext.formatting2.regionaccess.ITextRegionDiffBuilder;
import org.eclipse.xtext.formatting2.regionaccess.ITextRegionExtensions;
import org.eclipse.xtext.formatting2.regionaccess.internal.regionaccesstestlanguage.Delegate;
import org.eclipse.xtext.formatting2.regionaccess.internal.regionaccesstestlanguage.Delegation;
import org.eclipse.xtext.formatting2.regionaccess.internal.regionaccesstestlanguage.PrefixedUnassigned;
import org.eclipse.xtext.formatting2.regionaccess.internal.regionaccesstestlanguage.RegionaccesstestlanguagePackage;
import org.eclipse.xtext.formatting2.regionaccess.internal.regionaccesstestlanguage.ValueList;
import org.eclipse.xtext.formatting2.regionaccess.internal.tests.RegionAccessTestLanguageInjectorProvider;
import org.eclipse.xtext.serializer.impl.Serializer;
import org.eclipse.xtext.testing.InjectWith;
import org.eclipse.xtext.testing.XtextRunner;
import org.junit.Test;
import org.junit.runner.RunWith;
import com.google.inject.Inject;
/**
* @author Moritz Eysholdt - Initial contribution and API
*/
@InjectWith(RegionAccessTestLanguageInjectorProvider.class)
@RunWith(XtextRunner.class)
public class RegionAccessDiffTest {
@Inject
private RegionAccessTestHelper regionAccessTestHelper;
@Inject
private Serializer serializer;
@Test
public void testEmptyModification() throws Exception {
String model = "1 foo\n";
ITextRegionAccess access = regionAccessTestHelper.toTextRegionAccess(model);
String expectation1 =
"0 0 H\n" +
" B Simple'foo' Root\n" +
"0 1 S \"1\" Simple:'1'\n" +
"1 1 H \" \" Whitespace:TerminalRule'WS'\n" +
"2 3 S \"foo\" Simple:name=ID\n" +
" E Simple'foo' Root\n" +
"5 0 H\n";
regionAccessTestHelper.assertRegions(access, expectation1);
ITextRegionAccess modifiedAccess = regionAccessTestHelper.modify(access, (ITextRegionDiffBuilder it) -> {
});
String expectation2 =
"0 0 H\n" +
" B Simple'foo' Root\n" +
"0 1 S \"1\" Simple:'1'\n" +
"1 1 H \" \" Whitespace:TerminalRule'WS'\n" +
"2 3 S \"foo\" Simple:name=ID\n" +
" E Simple'foo' Root\n" +
"5 0 H\n";
regionAccessTestHelper.assertRegions(modifiedAccess, expectation2);
}
@Test
public void testSingleSemanticToken() throws Exception {
String model = "1 foo\n";
ITextRegionAccess access = regionAccessTestHelper.toTextRegionAccess(model);
ITextRegionAccess modifiedAccess = regionAccessTestHelper.modify(access, (ITextRegionDiffBuilder it) -> {
ITextRegionExtensions ext = access.getExtensions();
EObject root = access.regionForRootEObject().getSemanticElement();
ISemanticRegion foo = ext.allRegionsFor(root)
.feature(RegionaccesstestlanguagePackage.Literals.SIMPLE__NAME);
it.replace(foo, "baaar");
});
String expectation =
"0 0 H\n" +
" B Simple'foo' Root\n" +
"0 1 S \"1\" Simple:'1'\n" +
"1 1 H \" \" Whitespace:TerminalRule'WS'\n" +
"2 5 1 S \"baaar\" Simple:name=ID\n" +
" E Simple'foo' Root\n" +
"7 0 H\n" +
"------------ diff 1 ------------\n" +
"2 3 S \"foo\" Simple:name=ID\n";
regionAccessTestHelper.assertRegions(modifiedAccess, expectation);
}
@Test
public void testSerializeChildObject() throws Exception {
String model = "2 foo\n";
ITextRegionAccess access = regionAccessTestHelper.toTextRegionAccess(model);
ITextRegionAccess modifiedAccess = regionAccessTestHelper.modify(access, (ITextRegionDiffBuilder it) -> {
Delegate child = ((Delegation) access.regionForRootEObject().getSemanticElement()).getDelegate();
IEObjectRegion childRegion = access.regionForEObject(child);
child.setName("baaaz");
ITextRegionAccess textRegions = this.serializer.serializeToRegions(child);
it.replace(childRegion.getPreviousHiddenRegion(), childRegion.getNextHiddenRegion(), textRegions);
});
String expectation =
"0 0 H\n" +
" B Delegation Root\n" +
"0 1 S \"2\" Delegation:'2'\n" +
"1 1 1 H \" \" Whitespace:TerminalRule'WS'\n" +
" B Delegate'baaaz' Delegate path:Delegation/delegate\n" +
"2 5 1 S \"baaaz\" Delegate:name=ID\n" +
" E Delegate'baaaz' Delegate path:Delegation/delegate\n" +
" E Delegation Root\n" +
"7 0 1 H\n" +
"------------ diff 1 ------------\n" +
"1 1 H \" \" Whitespace:TerminalRule'WS'\n" +
"2 3 S \"foo\" Delegate:name=ID\n" +
"5 0 H\n";
regionAccessTestHelper.assertRegions(modifiedAccess, expectation);
}
@Test
public void testSerializeRootObject() throws Exception {
String model = "3 foo\n";
ITextRegionAccess access = regionAccessTestHelper.toTextRegionAccess(model);
ITextRegionAccess modifiedAccess = regionAccessTestHelper.modify(access, (ITextRegionDiffBuilder it) -> {
IEObjectRegion root = access.regionForRootEObject();
Delegate rootObj = (Delegate) root.getSemanticElement();
rootObj.setName("baaaz");
ITextRegionAccess textRegions = this.serializer.serializeToRegions(rootObj);
it.replace(root.getPreviousHiddenRegion(), root.getNextHiddenRegion(), textRegions);
});
String expectation =
"0 0 1 H\n" +
" B Delegate'baaaz' Root\n" +
"0 1 1 S \"3\" Unassigned:'3'\n" +
"1 1 1 H \" \" Whitespace:TerminalRule'WS'\n" +
"2 5 1 S \"baaaz\" Delegate:name=ID\n" +
" E Delegate'baaaz' Root\n" +
"7 0 1 H\n" +
"------------ diff 1 ------------\n" +
"0 0 H\n" +
"0 1 S \"3\" Unassigned:'3'\n" +
"1 1 H \" \" Whitespace:TerminalRule'WS'\n" +
"2 3 S \"foo\" Delegate:name=ID\n" +
"5 0 H\n";
regionAccessTestHelper.assertRegions(modifiedAccess, expectation);
}
@Test
public void testDeleteOne() throws Exception {
String model = "4/*1*/prefix/*2*/foo\n";
ITextRegionAccess access = regionAccessTestHelper.toTextRegionAccess(model);
ITextRegionAccess modifiedAccess = regionAccessTestHelper.modify(access, (ITextRegionDiffBuilder it) -> {
ITextRegionExtensions ext = access.getExtensions();
PrefixedUnassigned rootObj = (PrefixedUnassigned) access.regionForRootEObject().getSemanticElement();
ISemanticRegion prefix = ext.regionFor(rootObj.getDelegate()).keyword("prefix");
it.remove(prefix);
});
String expectation =
" 0 0 H\n" +
" B PrefixedUnassigned Root\n" +
" 0 1 S \"4\" PrefixedUnassigned:'4'\n" +
" 1 1 H \"/*1*/\" Comment:TerminalRule'ML_COMMENT' Association:CONTAINER\n" +
" 10 \"/*2*/\" Comment:TerminalRule'ML_COMMENT' Association:CONTAINER\n" +
" B Delegate'foo' PrefixedUnassigned:delegate=PrefixedDelegate path:PrefixedUnassigned/delegate\n" +
"11 3 S \"foo\" Delegate:name=ID\n" +
" E Delegate'foo' PrefixedUnassigned:delegate=PrefixedDelegate path:PrefixedUnassigned/delegate\n" +
" E PrefixedUnassigned Root\n" +
"14 0 H\n" +
"------------ diff 1 ------------\n" +
" 1 5 H \"/*1*/\" Comment:TerminalRule'ML_COMMENT' Association:CONTAINER\n" +
" 6 6 S \"prefix\" PrefixedDelegate:'prefix'\n" +
"12 5 H \"/*2*/\" Comment:TerminalRule'ML_COMMENT' Association:CONTAINER\n";
regionAccessTestHelper.assertRegions(modifiedAccess, expectation);
}
@Test
public void testDeleteTwo() throws Exception {
String model = "4/*1*/prefix/*2*/foo/*3*/\n";
ITextRegionAccess access = regionAccessTestHelper.toTextRegionAccess(model);
ITextRegionAccess modifiedAccess = regionAccessTestHelper.modify(access, (ITextRegionDiffBuilder it) -> {
ITextRegionExtensions ext = access.getExtensions();
PrefixedUnassigned rootObj = (PrefixedUnassigned) access.regionForRootEObject().getSemanticElement();
ISemanticRegion prefix = ext.regionFor(rootObj.getDelegate()).keyword("prefix");
ISemanticRegion foo = ext.regionFor(rootObj.getDelegate())
.feature(RegionaccesstestlanguagePackage.Literals.DELEGATE__NAME);
it.remove(prefix.getPreviousHiddenRegion(), foo.getNextHiddenRegion());
});
String expectation =
" 0 0 H\n" +
" B PrefixedUnassigned Root\n" +
" 0 1 S \"4\" PrefixedUnassigned:'4'\n" +
" E PrefixedUnassigned Root\n" +
" 1 1 H \"/*1*/\" Comment:TerminalRule'ML_COMMENT' Association:CONTAINER\n" +
" 10 \"/*3*/\" Comment:TerminalRule'ML_COMMENT' Association:CONTAINER\n" +
"------------ diff 1 ------------\n" +
" 1 5 H \"/*1*/\" Comment:TerminalRule'ML_COMMENT' Association:CONTAINER\n" +
" 6 6 S \"prefix\" PrefixedDelegate:'prefix'\n" +
"12 5 H \"/*2*/\" Comment:TerminalRule'ML_COMMENT' Association:CONTAINER\n" +
"17 3 S \"foo\" Delegate:name=ID\n" +
"20 5 H \"/*3*/\" Comment:TerminalRule'ML_COMMENT' Association:CONTAINER\n";
regionAccessTestHelper.assertRegions(modifiedAccess, expectation);
}
@Test
public void testInsertInsertReplace() throws Exception {
String model = "8 a\n";
ITextRegionAccess access = regionAccessTestHelper.toTextRegionAccess(model);
ITextRegionAccess modifiedAccess = regionAccessTestHelper.modify(access, (ITextRegionDiffBuilder it) -> {
ITextRegionExtensions ext = access.getExtensions();
ValueList rootObj = (ValueList) access.regionForRootEObject().getSemanticElement();
ISemanticRegion a = ext.regionFor(rootObj).keyword("8").getNextSemanticRegion();
it.replace(a.getNextHiddenRegion(), a.getNextHiddenRegion(), a.getPreviousHiddenRegion(),
a.getNextHiddenRegion());
it.replace(a.getNextHiddenRegion(), a.getNextHiddenRegion(), a.getPreviousHiddenRegion(),
a.getNextHiddenRegion());
it.replace(a, "new");
});
String expectation =
" 0 0 H\n" +
" B ValueList'[a]' Root\n" +
" 0 1 S \"8\" Root:'8'\n" +
" 1 1 H \" \" Whitespace:TerminalRule'WS'\n" +
" 2 3 2 S \"new\" ValueList:name+=ID\n" +
" 5 0 2 H\n" +
" 5 3 2 S \"new\" ValueList:name+=ID\n" +
" 8 0 2 H\n" +
" 8 3 2 S \"new\" ValueList:name+=ID\n" +
" E ValueList'[a]' Root\n" +
"11 0 2 H\n" +
"------------ diff 1 ------------\n" +
" 2 1 S \"a\" ValueList:name+=ID\n" +
"------------ diff 2 ------------\n" +
" 2 1 S \"a\" ValueList:name+=ID\n" +
" 3 0 H\n";
regionAccessTestHelper.assertRegions(modifiedAccess, expectation);
}
@Test
public void testInsertReplaceReplace() throws Exception {
String model = "8 a\n";
ITextRegionAccess access = regionAccessTestHelper.toTextRegionAccess(model);
ITextRegionAccess modifiedAccess = regionAccessTestHelper.modify(access, (ITextRegionDiffBuilder it) -> {
ITextRegionExtensions ext = access.getExtensions();
ValueList rootObj = (ValueList) access.regionForRootEObject().getSemanticElement();
ISemanticRegion a = ext.regionFor(rootObj).keyword("8").getNextSemanticRegion();
it.replace(a, "b");
it.replace(a, "c");
});
String expectation =
"0 0 H\n" +
" B ValueList'[a]' Root\n" +
"0 1 S \"8\" Root:'8'\n" +
"1 1 H \" \" Whitespace:TerminalRule'WS'\n" +
"2 1 1 S \"c\" ValueList:name+=ID\n" +
" E ValueList'[a]' Root\n" +
"3 0 H\n" +
"------------ diff 1 ------------\n" +
"2 1 S \"a\" ValueList:name+=ID\n";
regionAccessTestHelper.assertRegions(modifiedAccess, expectation);
}
@Test
public void testInsertBeforeComment() throws Exception {
String model = "8\n" +
"/**/\n" +
"a b\n";
ITextRegionAccess access = regionAccessTestHelper.toTextRegionAccess(model);
ITextRegionAccess modifiedAccess = regionAccessTestHelper.modify(access, (ITextRegionDiffBuilder it) -> {
ITextRegionExtensions ext = access.getExtensions();
ValueList rootObj = (ValueList) access.regionForRootEObject().getSemanticElement();
ISemanticRegion a = ext.regionFor(rootObj).keyword("8").getNextSemanticRegion();
ISemanticRegion b = a.getNextSemanticRegion();
it.replace(a.getPreviousHiddenRegion(), a.getPreviousHiddenRegion(), b.getPreviousHiddenRegion(),
b.getNextHiddenRegion());
});
String expectation =
" 0 0 H\n" +
" B ValueList'[a, b]' Root\n" +
" 0 1 S \"8\" Root:'8'\n" +
" 1 1 1 H \"\\n" +
"\" Whitespace:TerminalRule'WS'\n" +
" 2 1 1 S \"b\" ValueList:name+=ID\n" +
" 3 1 H \"/**/\" Comment:TerminalRule'ML_COMMENT' Association:PREVIOUS\n" +
" 5 \"\\n" +
"\" Whitespace:TerminalRule'WS'\n" +
" 8 1 S \"a\" ValueList:name+=ID\n" +
" 9 1 H \" \" Whitespace:TerminalRule'WS'\n" +
"10 1 S \"b\" ValueList:name+=ID\n" +
" E ValueList'[a, b]' Root\n" +
"11 0 H\n" +
"------------ diff 1 ------------\n" +
" 1 H \"\\n" +
"\" Whitespace:TerminalRule'WS'\n" +
" \"/**/\" Comment:TerminalRule'ML_COMMENT' Association:NEXT\n" +
" 6 \"\\n" +
"\" Whitespace:TerminalRule'WS'\n";
regionAccessTestHelper.assertRegions(modifiedAccess, expectation);
}
@Test
public void testMove() throws Exception {
String model = "8 a b c\n";
ITextRegionAccess access = regionAccessTestHelper.toTextRegionAccess(model);
ITextRegionAccess modifiedAccess = regionAccessTestHelper.modify(access, (ITextRegionDiffBuilder it) -> {
List<ISemanticRegion> regions = access.regionForRootEObject().getAllRegionsFor()
.features(RegionaccesstestlanguagePackage.Literals.VALUE_LIST__NAME);
ISemanticRegion a = regions.get(0);
ISemanticRegion b = regions.get(1);
it.move(b.getNextHiddenRegion(), a.getPreviousHiddenRegion(), a.getNextHiddenRegion());
});
String expectation =
"0 0 H\n" +
" B ValueList'[a, b, c]' Root\n" +
"0 1 S \"8\" Root:'8'\n" +
"1 1 H \" \" Whitespace:TerminalRule'WS'\n" +
" 2 \" \" Whitespace:TerminalRule'WS'\n" +
"3 1 S \"b\" ValueList:name+=ID\n" +
"4 1 2 H \" \" Whitespace:TerminalRule'WS'\n" +
"5 1 2 S \"a\" ValueList:name+=ID\n" +
"6 0 2 H\n" +
"6 1 S \"c\" ValueList:name+=ID\n" +
" E ValueList'[a, b, c]' Root\n" +
"7 0 H\n" +
"------------ diff 1 ------------\n" +
"1 1 H \" \" Whitespace:TerminalRule'WS'\n" +
"2 1 S \"a\" ValueList:name+=ID\n" +
"3 1 H \" \" Whitespace:TerminalRule'WS'\n" +
"------------ diff 2 ------------\n" +
"5 1 H \" \" Whitespace:TerminalRule'WS'\n" +
"6 1 S \"c\" ValueList:name+=ID\n";
regionAccessTestHelper.assertRegions(modifiedAccess, expectation);
}
}

View file

@ -1,305 +0,0 @@
/*******************************************************************************
* Copyright (c) 2017, 2020 TypeFox GmbH (http://www.typefox.io) 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.formatting2.regionaccess.internal
import com.google.inject.Inject
import org.eclipse.xtext.formatting2.regionaccess.internal.regionaccesstestlanguage.Delegate
import org.eclipse.xtext.formatting2.regionaccess.internal.regionaccesstestlanguage.Delegation
import org.eclipse.xtext.formatting2.regionaccess.internal.regionaccesstestlanguage.PrefixedUnassigned
import org.eclipse.xtext.formatting2.regionaccess.internal.regionaccesstestlanguage.RegionaccesstestlanguagePackage
import org.eclipse.xtext.formatting2.regionaccess.internal.tests.RegionAccessTestLanguageInjectorProvider
import org.eclipse.xtext.serializer.impl.Serializer
import org.eclipse.xtext.testing.InjectWith
import org.eclipse.xtext.testing.XtextRunner
import org.junit.Test
import org.junit.runner.RunWith
import org.eclipse.xtext.formatting2.regionaccess.internal.regionaccesstestlanguage.ValueList
/**
* @author Moritz Eysholdt - Initial contribution and API
*/
@InjectWith(RegionAccessTestLanguageInjectorProvider)
@RunWith(XtextRunner)
class RegionAccessDiffTest {
@Inject extension RegionAccessTestHelper
@Inject Serializer serializer
@Test def void testEmptyModification() throws Exception {
val access = '''
1 foo
'''.toTextRegionAccess
access === '''
0 0 H
B Simple'foo' Root
0 1 S "1" Simple:'1'
1 1 H " " Whitespace:TerminalRule'WS'
2 3 S "foo" Simple:name=ID
E Simple'foo' Root
5 0 H
'''
access.modify[] === '''
0 0 H
B Simple'foo' Root
0 1 S "1" Simple:'1'
1 1 H " " Whitespace:TerminalRule'WS'
2 3 S "foo" Simple:name=ID
E Simple'foo' Root
5 0 H
'''
}
@Test def void testSingleSemanticToken() throws Exception {
val access = '''
1 foo
'''.toTextRegionAccess
access.modify [
val extension ext = access.extensions
val root = access.regionForRootEObject.semanticElement
val foo = root.allRegionsFor.feature(RegionaccesstestlanguagePackage.Literals.SIMPLE__NAME)
replace(foo, "baaar")
] === '''
0 0 H
B Simple'foo' Root
0 1 S "1" Simple:'1'
1 1 H " " Whitespace:TerminalRule'WS'
2 5 1 S "baaar" Simple:name=ID
E Simple'foo' Root
7 0 H
------------ diff 1 ------------
2 3 S "foo" Simple:name=ID
'''
}
@Test def void testSerializeChildObject() throws Exception {
val access = '''
2 foo
'''.toTextRegionAccess
access.modify [
val child = (access.regionForRootEObject.semanticElement as Delegation).delegate
val childRegion = access.regionForEObject(child)
child.name = "baaaz"
val textRegions = serializer.serializeToRegions(child)
replace(childRegion.previousHiddenRegion, childRegion.nextHiddenRegion, textRegions)
] === '''
0 0 H
B Delegation Root
0 1 S "2" Delegation:'2'
1 1 1 H " " Whitespace:TerminalRule'WS'
B Delegate'baaaz' Delegate path:Delegation/delegate
2 5 1 S "baaaz" Delegate:name=ID
E Delegate'baaaz' Delegate path:Delegation/delegate
E Delegation Root
7 0 1 H
------------ diff 1 ------------
1 1 H " " Whitespace:TerminalRule'WS'
2 3 S "foo" Delegate:name=ID
5 0 H
'''
}
@Test def void testSerializeRootObject() throws Exception {
val access = '''
3 foo
'''.toTextRegionAccess
access.modify [
val root = access.regionForRootEObject;
val rootObj = root.semanticElement as Delegate
rootObj.name = "baaaz"
val textRegions = serializer.serializeToRegions(rootObj)
replace(root.previousHiddenRegion, root.nextHiddenRegion, textRegions)
] === '''
0 0 1 H
B Delegate'baaaz' Root
0 1 1 S "3" Unassigned:'3'
1 1 1 H " " Whitespace:TerminalRule'WS'
2 5 1 S "baaaz" Delegate:name=ID
E Delegate'baaaz' Root
7 0 1 H
------------ diff 1 ------------
0 0 H
0 1 S "3" Unassigned:'3'
1 1 H " " Whitespace:TerminalRule'WS'
2 3 S "foo" Delegate:name=ID
5 0 H
'''
}
@Test def void testDeleteOne() throws Exception {
val access = '''
4/*1*/prefix/*2*/foo
'''.toTextRegionAccess
access.modify [
val extension ext = access.extensions
val rootObj = access.regionForRootEObject.semanticElement as PrefixedUnassigned
val prefix = rootObj.delegate.regionFor.keyword("prefix")
remove(prefix)
] === '''
0 0 H
B PrefixedUnassigned Root
0 1 S "4" PrefixedUnassigned:'4'
1 1 H "/*1*/" Comment:TerminalRule'ML_COMMENT' Association:CONTAINER
10 "/*2*/" Comment:TerminalRule'ML_COMMENT' Association:CONTAINER
B Delegate'foo' PrefixedUnassigned:delegate=PrefixedDelegate path:PrefixedUnassigned/delegate
11 3 S "foo" Delegate:name=ID
E Delegate'foo' PrefixedUnassigned:delegate=PrefixedDelegate path:PrefixedUnassigned/delegate
E PrefixedUnassigned Root
14 0 H
------------ diff 1 ------------
1 5 H "/*1*/" Comment:TerminalRule'ML_COMMENT' Association:CONTAINER
6 6 S "prefix" PrefixedDelegate:'prefix'
12 5 H "/*2*/" Comment:TerminalRule'ML_COMMENT' Association:CONTAINER
'''
}
@Test def void testDeleteTwo() throws Exception {
val access = '''
4/*1*/prefix/*2*/foo/*3*/
'''.toTextRegionAccess
access.modify [
val extension ext = access.extensions
val rootObj = access.regionForRootEObject.semanticElement as PrefixedUnassigned
val prefix = rootObj.delegate.regionFor.keyword("prefix")
val foo = rootObj.delegate.regionFor.feature(RegionaccesstestlanguagePackage.Literals.DELEGATE__NAME)
remove(prefix.previousHiddenRegion, foo.nextHiddenRegion)
] === '''
0 0 H
B PrefixedUnassigned Root
0 1 S "4" PrefixedUnassigned:'4'
E PrefixedUnassigned Root
1 1 H "/*1*/" Comment:TerminalRule'ML_COMMENT' Association:CONTAINER
10 "/*3*/" Comment:TerminalRule'ML_COMMENT' Association:CONTAINER
------------ diff 1 ------------
1 5 H "/*1*/" Comment:TerminalRule'ML_COMMENT' Association:CONTAINER
6 6 S "prefix" PrefixedDelegate:'prefix'
12 5 H "/*2*/" Comment:TerminalRule'ML_COMMENT' Association:CONTAINER
17 3 S "foo" Delegate:name=ID
20 5 H "/*3*/" Comment:TerminalRule'ML_COMMENT' Association:CONTAINER
'''
}
@Test def void testInsertInsertReplace() throws Exception {
val access = '''
8 a
'''.toTextRegionAccess
access.modify [
val extension ext = access.extensions
val rootObj = access.regionForRootEObject.semanticElement as ValueList
val a = rootObj.regionFor.keyword("8").nextSemanticRegion
replace(a.nextHiddenRegion, a.nextHiddenRegion, a.previousHiddenRegion, a.nextHiddenRegion)
replace(a.nextHiddenRegion, a.nextHiddenRegion, a.previousHiddenRegion, a.nextHiddenRegion)
replace(a, "new")
] === '''
0 0 H
B ValueList'[a]' Root
0 1 S "8" Root:'8'
1 1 H " " Whitespace:TerminalRule'WS'
2 3 2 S "new" ValueList:name+=ID
5 0 2 H
5 3 2 S "new" ValueList:name+=ID
8 0 2 H
8 3 2 S "new" ValueList:name+=ID
E ValueList'[a]' Root
11 0 2 H
------------ diff 1 ------------
2 1 S "a" ValueList:name+=ID
------------ diff 2 ------------
2 1 S "a" ValueList:name+=ID
3 0 H
'''
}
@Test def void testInsertReplaceReplace() throws Exception {
val access = '''
8 a
'''.toTextRegionAccess
access.modify [
val extension ext = access.extensions
val rootObj = access.regionForRootEObject.semanticElement as ValueList
val a = rootObj.regionFor.keyword("8").nextSemanticRegion
replace(a, "b")
replace(a, "c")
] === '''
0 0 H
B ValueList'[a]' Root
0 1 S "8" Root:'8'
1 1 H " " Whitespace:TerminalRule'WS'
2 1 1 S "c" ValueList:name+=ID
E ValueList'[a]' Root
3 0 H
------------ diff 1 ------------
2 1 S "a" ValueList:name+=ID
'''
}
@Test def void testInsertBeforeComment() throws Exception {
val access = '''
8
/**/
a b
'''.toTextRegionAccess
access.modify [
val extension ext = access.extensions
val rootObj = access.regionForRootEObject.semanticElement as ValueList
val a = rootObj.regionFor.keyword("8").nextSemanticRegion
val b = a.nextSemanticRegion
replace(a.previousHiddenRegion, a.previousHiddenRegion, b.previousHiddenRegion, b.nextHiddenRegion)
] === '''
0 0 H
B ValueList'[a, b]' Root
0 1 S "8" Root:'8'
1 1 1 H "\n" Whitespace:TerminalRule'WS'
2 1 1 S "b" ValueList:name+=ID
3 1 H "/**/" Comment:TerminalRule'ML_COMMENT' Association:PREVIOUS
5 "\n" Whitespace:TerminalRule'WS'
8 1 S "a" ValueList:name+=ID
9 1 H " " Whitespace:TerminalRule'WS'
10 1 S "b" ValueList:name+=ID
E ValueList'[a, b]' Root
11 0 H
------------ diff 1 ------------
1 H "\n" Whitespace:TerminalRule'WS'
"/**/" Comment:TerminalRule'ML_COMMENT' Association:NEXT
6 "\n" Whitespace:TerminalRule'WS'
'''
}
@Test def void testMove() throws Exception {
val access = '''
8 a b c
'''.toTextRegionAccess
access.modify [
val regions = access.regionForRootEObject.allRegionsFor.features(RegionaccesstestlanguagePackage.Literals.VALUE_LIST__NAME)
val a = regions.get(0)
val b = regions.get(1)
move(b.nextHiddenRegion, a.previousHiddenRegion, a.nextHiddenRegion)
] === '''
0 0 H
B ValueList'[a, b, c]' Root
0 1 S "8" Root:'8'
1 1 H " " Whitespace:TerminalRule'WS'
2 " " Whitespace:TerminalRule'WS'
3 1 S "b" ValueList:name+=ID
4 1 2 H " " Whitespace:TerminalRule'WS'
5 1 2 S "a" ValueList:name+=ID
6 0 2 H
6 1 S "c" ValueList:name+=ID
E ValueList'[a, b, c]' Root
7 0 H
------------ diff 1 ------------
1 1 H " " Whitespace:TerminalRule'WS'
2 1 S "a" ValueList:name+=ID
3 1 H " " Whitespace:TerminalRule'WS'
------------ diff 2 ------------
5 1 H " " Whitespace:TerminalRule'WS'
6 1 S "c" ValueList:name+=ID
'''
}
}

View file

@ -57,7 +57,7 @@ public class RegionAccessTestHelper {
return modified;
}
public void operator_tripleEquals(ITextRegionAccess access, CharSequence expectation) {
public void assertRegions(ITextRegionAccess access, CharSequence expectation) {
if (access instanceof ITextRegionAccessDiff) {
assertDiffs((ITextRegionAccessDiff) access);
}

View file

@ -0,0 +1,529 @@
/**
* Copyright (c) 2015, 2021 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.serializer;
import org.eclipse.xtend2.lib.StringConcatenation;
import org.eclipse.xtext.AbstractElement;
import org.eclipse.xtext.Grammar;
import org.eclipse.xtext.GrammarUtil;
import org.eclipse.xtext.RuleCall;
import org.eclipse.xtext.grammaranalysis.impl.GrammarElementTitleSwitch;
import org.eclipse.xtext.serializer.analysis.IGrammarPDAProvider;
import org.eclipse.xtext.serializer.analysis.ISerState;
import org.eclipse.xtext.serializer.analysis.SerializationContextMap;
import org.eclipse.xtext.serializer.analysis.SerializationContextMap.Entry;
import org.eclipse.xtext.testing.InjectWith;
import org.eclipse.xtext.testing.XtextRunner;
import org.eclipse.xtext.testing.util.ParseHelper;
import org.eclipse.xtext.testing.validation.ValidationTestHelper;
import org.eclipse.xtext.tests.XtextInjectorProvider;
import org.eclipse.xtext.util.EmfFormatter;
import org.eclipse.xtext.util.Strings;
import org.eclipse.xtext.util.formallang.NfaUtil;
import org.eclipse.xtext.util.formallang.Pda;
import org.eclipse.xtext.util.formallang.PdaListFormatter;
import org.eclipse.xtext.util.formallang.PdaToDot;
import org.eclipse.xtext.xbase.lib.IterableExtensions;
import org.junit.Assert;
import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
import com.google.common.base.Function;
import com.google.common.base.Joiner;
import com.google.common.base.Predicates;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import com.google.inject.Inject;
/**
* @author Moritz Eysholdt - Initial contribution and API
*/
@RunWith(XtextRunner.class)
@InjectWith(XtextInjectorProvider.class)
public class GrammarPDAProviderTest {
@Inject
private IGrammarPDAProvider pdaProvider;
@Inject
private ParseHelper<Grammar> parser;
@Inject
private ValidationTestHelper validator;
@Test
public void testUnassignedAction() throws Exception {
String model = "Rule: {Action};\n";
String expected =
"Rule:\n" +
" start -> {Action}\n" +
" {Action} -> stop\n";
Assert.assertEquals(expected, toPda(model));
}
@Test
public void testAssignedAction() throws Exception {
String model = "Rule: {Foo} {Action.feat=current};\n";
String expected =
"Rule:\n" +
" start -> {Foo}\n" +
" {Action.feat=} -> stop\n" +
" {Foo} -> {Action.feat=}\n";
Assert.assertEquals(expected, toPda(model));
}
@Test
public void testAssignedTerminalRuleCall() throws Exception {
String model = "Rule: name=ID;\n";
String expected =
"Rule:\n" +
" start -> name=ID\n" +
" name=ID -> stop\n";
Assert.assertEquals(expected, toPda(model));
}
@Test
public void testAssignedEObjectRuleCall() throws Exception {
String model =
"Rule: call=Called;\n" +
"Called: name=ID;\n";
String expected =
"Rule:\n" +
" start -> call=Called\n" +
" call=Called -> stop\n" +
"Called:\n" +
" start -> name=ID\n" +
" name=ID -> stop\n";
Assert.assertEquals(expected, toPda(model));
}
@Test
public void testAssignedDatatypeRuleCall() throws Exception {
String model =
"Rule: call=Called;\n" +
"Called: 'foo';\n";
String expected =
"Rule:\n" +
" start -> call=Called\n" +
" call=Called -> stop\n";
Assert.assertEquals(expected, toPda(model));
}
@Test
public void testUnassignedCalledAction() throws Exception {
String model =
"Rule: D1 | D2;\n" +
"D1: 'd1' A;\n" +
"D2: 'd2' A;\n" +
"A: f1=ID {A.l=current} f2=ID;\n";
String expected =
"Rule:\n" +
" start -> >>D1, >>D2\n" +
" 'd1' -> >>A\n" +
" 'd2' -> >>A\n" +
" <<A -> <<D1\n" +
" <<A -> <<D2\n" +
" <<D1 -> stop\n" +
" <<D2 -> stop\n" +
" >>A -> f1=ID\n" +
" >>A -> f1=ID\n" +
" >>D1 -> 'd1'\n" +
" >>D2 -> 'd2'\n" +
" f1=ID -> {A.l=}\n" +
" f2=ID -> <<A, <<A\n" +
" {A.l=} -> f2=ID\n" +
"D1:\n" +
" start -> 'd1'\n" +
" 'd1' -> >>A\n" +
" <<A -> stop\n" +
" >>A -> f1=ID\n" +
" f1=ID -> {A.l=}\n" +
" f2=ID -> <<A\n" +
" {A.l=} -> f2=ID\n" +
"D2:\n" +
" start -> 'd2'\n" +
" 'd2' -> >>A\n" +
" <<A -> stop\n" +
" >>A -> f1=ID\n" +
" f1=ID -> {A.l=}\n" +
" f2=ID -> <<A\n" +
" {A.l=} -> f2=ID\n" +
"A:\n" +
" start -> f1=ID\n" +
" f1=ID -> {A.l=}\n" +
" f2=ID -> stop\n" +
" {A.l=} -> f2=ID\n";
Assert.assertEquals(expected, toPda(model));
}
@Test
public void testUnassignedFragmentRuleCall() throws Exception {
String model =
"Rule: Called;\n" +
"fragment Called returns Abstract: name=ID;\n";
String expected =
"Rule:\n" +
" start -> >>Called\n" +
" <<Called -> stop\n" +
" >>Called -> name=ID\n" +
" name=ID -> <<Called\n";
Assert.assertEquals(expected, toPda(model));
}
@Test
public void testUnassignedDatatypeRule() throws Exception {
String model =
"Rule: val=ID Called;\n" +
"Called: 'kw1';\n";
String expected =
"Rule:\n" +
" start -> val=ID\n" +
" Called -> stop\n" +
" val=ID -> Called\n";
Assert.assertEquals(expected, toPda(model));
}
@Test
public void testUnassignedTerminalRule() throws Exception {
String model =
"Rule: val=ID Called;\n" +
"terminal Called: 'kw1';\n";
String expected =
"Rule:\n" +
" start -> val=ID\n" +
" Called -> stop\n" +
" val=ID -> Called\n";
Assert.assertEquals(expected, toPda(model));
}
@Test
public void testUnassignedParserRuleCall() throws Exception {
String model =
"Rule: Called;\n" +
"Called returns Sub: name=ID;\n";
String expected =
"Rule:\n" +
" start -> >>Called\n" +
" <<Called -> stop\n" +
" >>Called -> name=ID\n" +
" name=ID -> <<Called\n" +
"Called:\n" +
" start -> name=ID\n" +
" name=ID -> stop\n";
Assert.assertEquals(expected, toPda(model));
}
@Test
public void testUnassignedWildcardFragmentRuleCall() throws Exception {
String model =
"Rule: Called;\n" +
"fragment Called*: name=ID;\n";
String expected =
"Rule:\n" +
" start -> >>Called\n" +
" <<Called -> stop\n" +
" >>Called -> name=ID\n" +
" name=ID -> <<Called\n";
Assert.assertEquals(expected, toPda(model));
}
@Test
public void testGroup() throws Exception {
String model = "Rule: {Rule} 'a' 'b' 'c';\n";
String expected =
"Rule:\n" +
" start -> {Rule}\n" +
" 'a' -> 'b'\n" +
" 'b' -> 'c'\n" +
" 'c' -> stop\n" +
" {Rule} -> 'a'\n";
Assert.assertEquals(expected, toPda(model));
}
@Test
public void testAlternative() throws Exception {
String model = "Rule: {Rule} ('a' | 'b' | 'c');\n";
String expected =
"Rule:\n" +
" start -> {Rule}\n" +
" 'a' -> stop\n" +
" 'b' -> stop\n" +
" 'c' -> stop\n" +
" {Rule} -> 'a', 'b', 'c'\n";
Assert.assertEquals(expected, toPda(model));
}
@Test
public void testUnorderedGroup() throws Exception {
String model = "Rule: {Rule} ('a' & 'b' & 'c');\n";
String expected =
"Rule:\n" +
" start -> {Rule}\n" +
" 'a' -> 'a', 'b', 'c', stop\n" +
" 'b' -> 'a', 'b', 'c', stop\n" +
" 'c' -> 'a', 'b', 'c', stop\n" +
" {Rule} -> 'a', 'b', 'c'\n";
Assert.assertEquals(expected, toPda(model));
}
@Test
public void testUnorderedGroup2() throws Exception {
String model = "Rule: {Rule} ('a' & 'b'? & 'c'* & 'd'+);\n";
String expected =
"Rule:\n" +
" start -> {Rule}\n" +
" 'a' -> 'a', 'b', 'c', 'd', stop\n" +
" 'b' -> 'a', 'b', 'c', 'd', stop\n" +
" 'c' -> 'a', 'b', 'c', 'd', stop\n" +
" 'd' -> 'a', 'b', 'c', 'd', stop\n" +
" {Rule} -> 'a', 'b', 'c', 'd'\n";
Assert.assertEquals(expected, toPda(model));
}
@Test
public void testTwoAssignedEObjectRuleCalls() throws Exception {
String model = "Rule: foo1=Sub foo2=Sub; Sub: id='id';\n";
String expected =
"Rule:\n" +
" start -> foo1=Sub\n" +
" foo1=Sub -> foo2=Sub\n" +
" foo2=Sub -> stop\n" +
"Sub:\n" +
" start -> id='id'\n" +
" id='id' -> stop\n";
Assert.assertEquals(expected, toPda(model));
}
@Test
public void testRecursion() throws Exception {
String model = "Recursion: val=ID | '(' Recursion ')';\n";
String expected =
"Recursion:\n" +
" start -> '(', val=ID\n" +
" '(' -> >>Recursion\n" +
" ')' -> <<Recursion, stop\n" +
" <<Recursion -> ')'\n" +
" >>Recursion -> '(', val=ID\n" +
" val=ID -> <<Recursion, stop\n";
Assert.assertEquals(expected, toPda(model));
}
@Test
public void testExpression1() throws Exception {
String model =
"Exp: 'kw' Addit; Addit returns Exp: Prim ({Add.left=current} '+' right=Prim)*; Prim returns Exp: {Val} val=ID;\n";
String expected =
"Exp:\n" +
" start -> 'kw'\n" +
" '+' -> right=Prim\n" +
" 'kw' -> >>Addit\n" +
" <<Addit -> stop\n" +
" <<Prim -> <<Addit, {Add.left=}\n" +
" >>Addit -> >>Prim\n" +
" >>Prim -> {Val}\n" +
" right=Prim -> <<Addit, {Add.left=}\n" +
" val=ID -> <<Prim\n" +
" {Add.left=} -> '+'\n" +
" {Val} -> val=ID\n" +
"Addit:\n" +
" start -> >>Prim\n" +
" '+' -> right=Prim\n" +
" <<Prim -> stop, {Add.left=}\n" +
" >>Prim -> {Val}\n" +
" right=Prim -> stop, {Add.left=}\n" +
" val=ID -> <<Prim\n" +
" {Add.left=} -> '+'\n" +
" {Val} -> val=ID\n" +
"Prim:\n" +
" start -> {Val}\n" +
" val=ID -> stop\n" +
" {Val} -> val=ID\n";
Assert.assertEquals(expected, toPda(model));
}
@Test
public void testActionAlternative() throws Exception {
String model =
"Greeting: '(' Greeting ')' {Foo.child=current} | val=ID;\n";
String expected =
"Greeting:\n" +
" start -> '(', val=ID\n" +
" '(' -> >>Greeting\n" +
" ')' -> {Foo.child=}\n" +
" <<Greeting -> ')'\n" +
" >>Greeting -> '(', val=ID\n" +
" val=ID -> <<Greeting, stop\n" +
" {Foo.child=} -> <<Greeting, stop\n";
Assert.assertEquals(expected, toPda(model));
}
@Test
@Ignore
public void testFragmentWithAction() throws Exception {
String model =
"R: f1=ID F; fragment F returns R: {A.prev=current} f2=ID;\n";
String expected =
"R:\n" +
" start -> f1=ID\n" +
" <<F -> stop\n" +
" >>F -> {A.prev=}\n" +
" f1=ID -> >>F\n" +
" f2=ID -> <<F\n" +
" {A.prev=} -> f2=ID\n";
Assert.assertEquals(expected, toPda(model));
}
@Test
@Ignore
public void testFragmentWithAction2() throws Exception {
String model =
"R: 'kw1a' f1=ID 'kw1b' F; fragment F returns R: 'kw2a' {A.prev=current} 'kw2b' f2=ID 'kw2c';\n";
String expected =
"R:\n" +
" start -> f1=ID\n" +
" <<F -> stop\n" +
" >>F -> {A.prev=}\n" +
" f1=ID -> >>F\n" +
" f2=ID -> <<F\n" +
" {A.prev=} -> f2=ID\n";
Assert.assertEquals(expected, toPda(model));
}
@Test
public void testParameter1() throws Exception {
String model =
"M: 'kw1' s=S<true> | 'kw2' s=S<false>;\n" +
"S <P>: <P> v1=ID | <!P> v2=ID; \n";
String expected =
"M:\n" +
" start -> 'kw1', 'kw2'\n" +
" 'kw1' -> (s=S|)\n" +
" 'kw2' -> (|s=S)\n" +
" (s=S|) -> stop\n" +
" (|s=S) -> stop\n" +
"S<P>:\n" +
" start -> v1=ID\n" +
" v1=ID -> stop\n" +
"S:\n" +
" start -> v2=ID\n" +
" v2=ID -> stop\n";
Assert.assertEquals(expected, toPda(model));
}
@Test
public void testDoubleFragment() throws Exception {
String model =
"R: F1 F2;\n" +
"fragment F1: f1=ID; \n" +
"fragment F2: f2=ID; \n";
String expected =
"R:\n" +
" start -> >>F1\n" +
" <<F1 -> >>F2\n" +
" <<F2 -> stop\n" +
" >>F1 -> f1=ID\n" +
" >>F2 -> f2=ID\n" +
" f1=ID -> <<F1\n" +
" f2=ID -> <<F2\n";
Assert.assertEquals(expected, toPda(model));
}
@Test
public void testFragmentLoop() throws Exception {
String model =
"R: F+;\n" +
"fragment F: f+=ID; \n";
String expected =
"R:\n" +
" start -> >>F\n" +
" <<F -> >>F, stop\n" +
" >>F -> f+=ID\n" +
" f+=ID -> <<F\n";
Assert.assertEquals(expected, toPda(model));
}
@Test
public void testParameterizedDoubleDelegation() throws Exception {
String model =
"R: F<true> | F<false>;\n" +
"fragment F<X>: f+=ID;\n";
String expected =
"R:\n" +
" start -> >>F, >>F\n" +
" <<F -> stop\n" +
" <<F -> stop\n" +
" >>F -> f+=ID\n" +
" >>F -> f+=ID\n" +
" f+=ID -> <<F, <<F\n";
Assert.assertEquals(expected, toPda(model));
}
private String toPda(CharSequence rulesText) throws Exception {
String grammarText = "grammar org.eclipse.xtext.serializer.GrammarPDAProviderTestLanguage with org.eclipse.xtext.common.Terminals\n"
+ "generate GrammarPDAProviderTest 'http://www.eclipse.org/2010/tmf/xtext/GrammarPDAProviderTestLanguage'\n"
+ rulesText;
Grammar grammar = parser.parse(grammarText);
validator.assertNoErrors(grammar);
SerializationContextMap<Pda<ISerState, RuleCall>> pdas = pdaProvider.getGrammarPDAs(grammar);
pdas.values().forEach(it -> {
assertNoLeakedGrammarElements(grammar, it.getValue());
});
Iterable<ISerializationContext> contexts = Iterables
.concat(Lists.transform(pdas.values(), Entry<Pda<ISerState, RuleCall>>::getContexts));
return Strings.toUnixLineSeparator(
Joiner.on("").join(Lists.transform(IterableExtensions.sort(contexts), (ISerializationContext it) -> {
StringConcatenation b = new StringConcatenation();
b.append(it);
b.append(":");
b.newLineIfNotEmpty();
b.append(" ");
b.append(toListString(pdas.get(it)), " ");
b.newLineIfNotEmpty();
return b.toString();
})));
}
private void assertNoLeakedGrammarElements(Grammar grammar, Pda<ISerState, RuleCall> pda) {
for (AbstractElement ele : Iterables.filter(
Iterables.transform(new NfaUtil().collect(pda), ISerState::getGrammarElement), Predicates.notNull())) {
Grammar actual = GrammarUtil.getGrammar(ele);
if (actual != grammar) {
Assert.fail("Element " + EmfFormatter.objPath(ele) + " leaked!");
}
}
}
protected void toDot(Pda<ISerState, RuleCall> pda, String name) throws Exception {
String test = Thread.currentThread().getStackTrace()[6].getMethodName();
new PdaToDot<Object, Object>().draw(pda, "dot2/" + test + "_" + name + ".pdf", "-T pdf");
}
private String toListString(Pda<ISerState, RuleCall> pda) {
GrammarElementTitleSwitch ts = new GrammarElementTitleSwitch().showAssignments().hideCardinality()
.showQualified();
PdaListFormatter<ISerState, RuleCall> formatter = new PdaListFormatter<ISerState, RuleCall>();
formatter.setStateFormatter((Function<ISerState, String>) (ISerState it) -> {
if (it.getType() != null) {
switch (it.getType()) {
case START:
return "start";
case STOP:
return "stop";
default:
return ts.apply(it.getGrammarElement());
}
} else {
return ts.apply(it.getGrammarElement());
}
});
formatter.setStackitemFormatter(new GrammarElementTitleSwitch().showAssignments().hideCardinality());
formatter.sortFollowers();
return formatter.format(pda) + "\n";
}
}

View file

@ -1,529 +0,0 @@
/*******************************************************************************
* Copyright (c) 2015, 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.serializer
import com.google.inject.Inject
import org.eclipse.xtext.Grammar
import org.eclipse.xtext.GrammarUtil
import org.eclipse.xtext.RuleCall
import org.eclipse.xtext.grammaranalysis.impl.GrammarElementTitleSwitch
import org.eclipse.xtext.serializer.analysis.IGrammarPDAProvider
import org.eclipse.xtext.serializer.analysis.ISerState
import org.eclipse.xtext.testing.InjectWith
import org.eclipse.xtext.testing.XtextRunner
import org.eclipse.xtext.testing.util.ParseHelper
import org.eclipse.xtext.testing.validation.ValidationTestHelper
import org.eclipse.xtext.tests.XtextInjectorProvider
import org.eclipse.xtext.util.EmfFormatter
import org.eclipse.xtext.util.formallang.NfaUtil
import org.eclipse.xtext.util.formallang.Pda
import org.eclipse.xtext.util.formallang.PdaListFormatter
import org.eclipse.xtext.util.formallang.PdaToDot
import org.junit.Assert
import org.junit.Ignore
import org.junit.Test
import org.junit.runner.RunWith
/**
* @author Moritz Eysholdt - Initial contribution and API
*/
@RunWith(XtextRunner)
@InjectWith(XtextInjectorProvider)
class GrammarPDAProviderTest {
@Inject IGrammarPDAProvider pdaProvider
@Inject ParseHelper<Grammar> parser
@Inject ValidationTestHelper validator
@Test def void testUnassignedAction() throws Exception {
val actual = '''
Rule: {Action};
'''.toPda
val expected = '''
Rule:
start -> {Action}
{Action} -> stop
'''
Assert.assertEquals(expected, actual)
}
@Test def void testAssignedAction() throws Exception {
val actual = '''
Rule: {Foo} {Action.feat=current};
'''.toPda
val expected = '''
Rule:
start -> {Foo}
{Action.feat=} -> stop
{Foo} -> {Action.feat=}
'''
Assert.assertEquals(expected, actual)
}
@Test def void testAssignedTerminalRuleCall() throws Exception {
val actual = '''
Rule: name=ID;
'''.toPda
val expected = '''
Rule:
start -> name=ID
name=ID -> stop
'''
Assert.assertEquals(expected, actual)
}
@Test def void testAssignedEObjectRuleCall() throws Exception {
val actual = '''
Rule: call=Called;
Called: name=ID;
'''.toPda
val expected = '''
Rule:
start -> call=Called
call=Called -> stop
Called:
start -> name=ID
name=ID -> stop
'''
Assert.assertEquals(expected, actual)
}
@Test def void testAssignedDatatypeRuleCall() throws Exception {
val actual = '''
Rule: call=Called;
Called: "foo";
'''.toPda
val expected = '''
Rule:
start -> call=Called
call=Called -> stop
'''
Assert.assertEquals(expected, actual)
}
@Test def void testUnassignedCalledAction() throws Exception {
val actual = '''
Rule: D1 | D2;
D1: 'd1' A;
D2: 'd2' A;
A: f1=ID {A.l=current} f2=ID;
'''.toPda
val expected = '''
Rule:
start -> >>D1, >>D2
'd1' -> >>A
'd2' -> >>A
<<A -> <<D1
<<A -> <<D2
<<D1 -> stop
<<D2 -> stop
>>A -> f1=ID
>>A -> f1=ID
>>D1 -> 'd1'
>>D2 -> 'd2'
f1=ID -> {A.l=}
f2=ID -> <<A, <<A
{A.l=} -> f2=ID
D1:
start -> 'd1'
'd1' -> >>A
<<A -> stop
>>A -> f1=ID
f1=ID -> {A.l=}
f2=ID -> <<A
{A.l=} -> f2=ID
D2:
start -> 'd2'
'd2' -> >>A
<<A -> stop
>>A -> f1=ID
f1=ID -> {A.l=}
f2=ID -> <<A
{A.l=} -> f2=ID
A:
start -> f1=ID
f1=ID -> {A.l=}
f2=ID -> stop
{A.l=} -> f2=ID
'''
Assert.assertEquals(expected, actual)
}
@Test def void testUnassignedFragmentRuleCall() throws Exception {
val actual = '''
Rule: Called;
fragment Called returns Abstract: name=ID;
'''.toPda
val expected = '''
Rule:
start -> >>Called
<<Called -> stop
>>Called -> name=ID
name=ID -> <<Called
'''
Assert.assertEquals(expected, actual)
}
@Test def void testUnassignedDatatypeRule() throws Exception {
val actual = '''
Rule: val=ID Called;
Called: 'kw1';
'''.toPda
val expected = '''
Rule:
start -> val=ID
Called -> stop
val=ID -> Called
'''
Assert.assertEquals(expected, actual)
}
@Test def void testUnassignedTerminalRule() throws Exception {
val actual = '''
Rule: val=ID Called;
terminal Called: 'kw1';
'''.toPda
val expected = '''
Rule:
start -> val=ID
Called -> stop
val=ID -> Called
'''
Assert.assertEquals(expected, actual)
}
@Test def void testUnassignedParserRuleCall() throws Exception {
val actual = '''
Rule: Called;
Called returns Sub: name=ID;
'''.toPda
val expected = '''
Rule:
start -> >>Called
<<Called -> stop
>>Called -> name=ID
name=ID -> <<Called
Called:
start -> name=ID
name=ID -> stop
'''
Assert.assertEquals(expected, actual)
}
@Test def void testUnassignedWildcardFragmentRuleCall() throws Exception {
val actual = '''
Rule: Called;
fragment Called*: name=ID;
'''.toPda
val expected = '''
Rule:
start -> >>Called
<<Called -> stop
>>Called -> name=ID
name=ID -> <<Called
'''
Assert.assertEquals(expected, actual)
}
@Test def void testGroup() throws Exception {
val actual = '''
Rule: {Rule} 'a' 'b' 'c';
'''.toPda
val expected = '''
Rule:
start -> {Rule}
'a' -> 'b'
'b' -> 'c'
'c' -> stop
{Rule} -> 'a'
'''
Assert.assertEquals(expected, actual)
}
@Test def void testAlternative() throws Exception {
val actual = '''
Rule: {Rule} ('a' | 'b' | 'c');
'''.toPda
val expected = '''
Rule:
start -> {Rule}
'a' -> stop
'b' -> stop
'c' -> stop
{Rule} -> 'a', 'b', 'c'
'''
Assert.assertEquals(expected, actual)
}
@Test def void testUnorderedGroup() throws Exception {
val actual = '''
Rule: {Rule} ('a' & 'b' & 'c');
'''.toPda
val expected = '''
Rule:
start -> {Rule}
'a' -> 'a', 'b', 'c', stop
'b' -> 'a', 'b', 'c', stop
'c' -> 'a', 'b', 'c', stop
{Rule} -> 'a', 'b', 'c'
'''
Assert.assertEquals(expected, actual)
}
@Test def void testUnorderedGroup2() throws Exception {
val actual = '''
Rule: {Rule} ('a' & 'b'? & 'c'* & 'd'+);
'''.toPda
val expected = '''
Rule:
start -> {Rule}
'a' -> 'a', 'b', 'c', 'd', stop
'b' -> 'a', 'b', 'c', 'd', stop
'c' -> 'a', 'b', 'c', 'd', stop
'd' -> 'a', 'b', 'c', 'd', stop
{Rule} -> 'a', 'b', 'c', 'd'
'''
Assert.assertEquals(expected, actual)
}
@Test def void testTwoAssignedEObjectRuleCalls() throws Exception {
val actual = '''
Rule: foo1=Sub foo2=Sub; Sub: id='id';
'''.toPda
val expected = '''
Rule:
start -> foo1=Sub
foo1=Sub -> foo2=Sub
foo2=Sub -> stop
Sub:
start -> id='id'
id='id' -> stop
'''
Assert.assertEquals(expected, actual)
}
@Test def void testRecursion() throws Exception {
val actual = '''
Recursion: val=ID | '(' Recursion ')';
'''.toPda
val expected = '''
Recursion:
start -> '(', val=ID
'(' -> >>Recursion
')' -> <<Recursion, stop
<<Recursion -> ')'
>>Recursion -> '(', val=ID
val=ID -> <<Recursion, stop
'''
Assert.assertEquals(expected, actual)
}
@Test def void testExpression1() throws Exception {
val actual = '''
Exp: 'kw' Addit; Addit returns Exp: Prim ({Add.left=current} '+' right=Prim)*; Prim returns Exp: {Val} val=ID;
'''.toPda
val expected = '''
Exp:
start -> 'kw'
'+' -> right=Prim
'kw' -> >>Addit
<<Addit -> stop
<<Prim -> <<Addit, {Add.left=}
>>Addit -> >>Prim
>>Prim -> {Val}
right=Prim -> <<Addit, {Add.left=}
val=ID -> <<Prim
{Add.left=} -> '+'
{Val} -> val=ID
Addit:
start -> >>Prim
'+' -> right=Prim
<<Prim -> stop, {Add.left=}
>>Prim -> {Val}
right=Prim -> stop, {Add.left=}
val=ID -> <<Prim
{Add.left=} -> '+'
{Val} -> val=ID
Prim:
start -> {Val}
val=ID -> stop
{Val} -> val=ID
'''
Assert.assertEquals(expected, actual)
}
@Test def void testActionAlternative() throws Exception {
val actual = '''
Greeting: '(' Greeting ')' {Foo.child=current} | val=ID;
'''.toPda
val expected = '''
Greeting:
start -> '(', val=ID
'(' -> >>Greeting
')' -> {Foo.child=}
<<Greeting -> ')'
>>Greeting -> '(', val=ID
val=ID -> <<Greeting, stop
{Foo.child=} -> <<Greeting, stop
'''
Assert.assertEquals(expected, actual)
}
@Test @Ignore def void testFragmentWithAction() throws Exception {
val actual = '''
R: f1=ID F; fragment F returns R: {A.prev=current} f2=ID;
'''.toPda
val expected = '''
R:
start -> f1=ID
<<F -> stop
>>F -> {A.prev=}
f1=ID -> >>F
f2=ID -> <<F
{A.prev=} -> f2=ID
'''
Assert.assertEquals(expected, actual)
}
@Test @Ignore def void testFragmentWithAction2() throws Exception {
val actual = '''
R: 'kw1a' f1=ID 'kw1b' F; fragment F returns R: 'kw2a' {A.prev=current} 'kw2b' f2=ID 'kw2c';
'''.toPda
val expected = '''
R:
start -> f1=ID
<<F -> stop
>>F -> {A.prev=}
f1=ID -> >>F
f2=ID -> <<F
{A.prev=} -> f2=ID
'''
Assert.assertEquals(expected, actual)
}
@Test def void testParameter1() throws Exception {
val actual = '''
M: "kw1" s=S<true> | "kw2" s=S<false>;
S <P>: <P> v1=ID | <!P> v2=ID;
'''.toPda
val expected = '''
M:
start -> 'kw1', 'kw2'
'kw1' -> (s=S|)
'kw2' -> (|s=S)
(s=S|) -> stop
(|s=S) -> stop
S<P>:
start -> v1=ID
v1=ID -> stop
S:
start -> v2=ID
v2=ID -> stop
'''
Assert.assertEquals(expected, actual)
}
@Test def void testDoubleFragment() throws Exception {
val actual = '''
R: F1 F2;
fragment F1: f1=ID;
fragment F2: f2=ID;
'''.toPda
val expected = '''
R:
start -> >>F1
<<F1 -> >>F2
<<F2 -> stop
>>F1 -> f1=ID
>>F2 -> f2=ID
f1=ID -> <<F1
f2=ID -> <<F2
'''
Assert.assertEquals(expected, actual)
}
@Test def void testFragmentLoop() throws Exception {
val actual = '''
R: F+;
fragment F: f+=ID;
'''.toPda
val expected = '''
R:
start -> >>F
<<F -> >>F, stop
>>F -> f+=ID
f+=ID -> <<F
'''
Assert.assertEquals(expected, actual)
}
@Test def void testParameterizedDoubleDelegation() throws Exception {
val actual = '''
R: F<true> | F<false>;
fragment F<X>: f+=ID;
'''.toPda
val expected = '''
R:
start -> >>F, >>F
<<F -> stop
<<F -> stop
>>F -> f+=ID
>>F -> f+=ID
f+=ID -> <<F, <<F
'''
Assert.assertEquals(expected, actual)
}
def private String toPda(CharSequence rulesText) throws Exception {
val grammar = parser.parse('''
grammar org.eclipse.xtext.serializer.GrammarPDAProviderTestLanguage with org.eclipse.xtext.common.Terminals
generate GrammarPDAProviderTest "http://www.eclipse.org/2010/tmf/xtext/GrammarPDAProviderTestLanguage"
«rulesText»
''')
validator.assertNoErrors(grammar)
val pdas = pdaProvider.getGrammarPDAs(grammar)
pdas.values.forEach[assertNoLeakedGrammarElements(grammar, value)]
// pdas.values.forEach[value.toDot(it.contexts.join("-"))]
return pdas.values.map[contexts].flatten.sort.map [
'''
«it»:
«pdas.get(it).toListString»
'''
].join
}
def private void assertNoLeakedGrammarElements(Grammar grammar, Pda<ISerState, RuleCall> pda) {
for (ele : new NfaUtil().collect(pda).map[grammarElement].filterNull) {
val actual = GrammarUtil.getGrammar(ele)
if (actual !== grammar) {
Assert.fail("Element " + EmfFormatter.objPath(ele) + " leaked!")
}
}
}
def protected toDot(Pda<ISerState, RuleCall> pda, String name) throws Exception {
val test = Thread.currentThread.stackTrace.get(6).methodName
new PdaToDot().draw(pda, "dot2/" + test + "_" + name + ".pdf", "-T pdf")
}
def private toListString(Pda<ISerState, RuleCall> pda) {
val ts = new GrammarElementTitleSwitch().showAssignments().hideCardinality().showQualified()
val formatter = new PdaListFormatter<ISerState, RuleCall>();
formatter.setStateFormatter [
switch (type) { case START: "start" case STOP: "stop" default: ts.apply(grammarElement) }
];
formatter.setStackitemFormatter(new GrammarElementTitleSwitch().showAssignments().hideCardinality());
formatter.sortFollowers();
return formatter.format(pda) + "\n"
}
}

View file

@ -1,562 +0,0 @@
/**
* Copyright (c) 2017, 2020 TypeFox GmbH (http://www.typefox.io) 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.formatting2.regionaccess.internal;
import com.google.inject.Inject;
import java.util.List;
import org.eclipse.xtend2.lib.StringConcatenation;
import org.eclipse.xtext.formatting2.regionaccess.ISemanticRegion;
import org.eclipse.xtext.formatting2.regionaccess.ITextRegionAccess;
import org.eclipse.xtext.formatting2.regionaccess.ITextRegionDiffBuilder;
import org.eclipse.xtext.formatting2.regionaccess.internal.regionaccesstestlanguage.RegionaccesstestlanguagePackage;
import org.eclipse.xtext.formatting2.regionaccess.internal.tests.RegionAccessTestLanguageInjectorProvider;
import org.eclipse.xtext.testing.InjectWith;
import org.eclipse.xtext.testing.XtextRunner;
import org.eclipse.xtext.xbase.lib.Extension;
import org.eclipse.xtext.xbase.lib.IterableExtensions;
import org.eclipse.xtext.xbase.lib.Procedures.Procedure1;
import org.junit.Test;
import org.junit.runner.RunWith;
/**
* @author Moritz Eysholdt - Initial contribution and API
*/
@InjectWith(RegionAccessTestLanguageInjectorProvider.class)
@RunWith(XtextRunner.class)
@SuppressWarnings("all")
public class RegionAccessCommentsTest {
@Inject
@Extension
private RegionAccessTestHelper _regionAccessTestHelper;
@Test
public void testDeleteFirstRegion1() throws Exception {
StringConcatenation _builder = new StringConcatenation();
_builder.append("/*h*/");
_builder.newLine();
_builder.newLine();
_builder.append("/*8*/");
_builder.newLine();
_builder.append("8 //8");
_builder.newLine();
_builder.append("/*a*/");
_builder.newLine();
_builder.append("a");
_builder.newLine();
final ITextRegionAccess access = this._regionAccessTestHelper.toTextRegionAccess(_builder);
final Procedure1<ITextRegionDiffBuilder> _function = (ITextRegionDiffBuilder it) -> {
final ISemanticRegion foo = access.regionForRootEObject().getAllRegionsFor().keyword("8");
it.remove(foo);
};
ITextRegionAccess _modify = this._regionAccessTestHelper.modify(access, _function);
StringConcatenation _builder_1 = new StringConcatenation();
_builder_1.append(" ");
_builder_1.append("0 1 H \"/*h*/\" Comment:TerminalRule\'ML_COMMENT\' Association:CONTAINER");
_builder_1.newLine();
_builder_1.append(" ");
_builder_1.append("\"\\n\\n\" Whitespace:TerminalRule\'WS\'");
_builder_1.newLine();
_builder_1.append(" ");
_builder_1.append("\"/*a*/\" Comment:TerminalRule\'ML_COMMENT\' Association:NEXT");
_builder_1.newLine();
_builder_1.append(" ");
_builder_1.append("13 \"\\n\" Whitespace:TerminalRule\'WS\'");
_builder_1.newLine();
_builder_1.append(" ");
_builder_1.append("B ValueList\'[a]\' Root");
_builder_1.newLine();
_builder_1.append("13 1 S \"a\" ValueList:name+=ID");
_builder_1.newLine();
_builder_1.append(" ");
_builder_1.append("E ValueList\'[a]\' Root");
_builder_1.newLine();
_builder_1.append("14 0 H");
_builder_1.newLine();
_builder_1.append("------------ diff 1 ------------");
_builder_1.newLine();
_builder_1.append(" ");
_builder_1.append("0 H \"/*h*/\" Comment:TerminalRule\'ML_COMMENT\' Association:CONTAINER");
_builder_1.newLine();
_builder_1.append(" ");
_builder_1.append("\"\\n\\n\" Whitespace:TerminalRule\'WS\'");
_builder_1.newLine();
_builder_1.append(" ");
_builder_1.append("\"/*8*/\" Comment:TerminalRule\'ML_COMMENT\' Association:NEXT");
_builder_1.newLine();
_builder_1.append(" ");
_builder_1.append("13 \"\\n\" Whitespace:TerminalRule\'WS\'");
_builder_1.newLine();
_builder_1.append("13 1 S \"8\" Root:\'8\'");
_builder_1.newLine();
_builder_1.append("14 H \" \" Whitespace:TerminalRule\'WS\'");
_builder_1.newLine();
_builder_1.append(" ");
_builder_1.append("\"//8\\n\" Comment:TerminalRule\'SL_COMMENT\' Association:PREVIOUS");
_builder_1.newLine();
_builder_1.append(" ");
_builder_1.append("\"/*a*/\" Comment:TerminalRule\'ML_COMMENT\' Association:NEXT");
_builder_1.newLine();
_builder_1.append(" ");
_builder_1.append("11 \"\\n\" Whitespace:TerminalRule\'WS\'");
_builder_1.newLine();
this._regionAccessTestHelper.operator_tripleEquals(_modify, _builder_1);
}
@Test
public void testDeleteFirstRegion2() throws Exception {
StringConcatenation _builder = new StringConcatenation();
_builder.append("/*h*/");
_builder.newLine();
_builder.newLine();
_builder.append("/*81*/");
_builder.newLine();
_builder.append("/*82*/");
_builder.newLine();
_builder.append("8 //8");
_builder.newLine();
_builder.append("/*a*/");
_builder.newLine();
_builder.append("a");
_builder.newLine();
final ITextRegionAccess access = this._regionAccessTestHelper.toTextRegionAccess(_builder);
final Procedure1<ITextRegionDiffBuilder> _function = (ITextRegionDiffBuilder it) -> {
final ISemanticRegion foo = access.regionForRootEObject().getAllRegionsFor().keyword("8");
it.remove(foo);
};
ITextRegionAccess _modify = this._regionAccessTestHelper.modify(access, _function);
StringConcatenation _builder_1 = new StringConcatenation();
_builder_1.append(" ");
_builder_1.append("0 1 H \"/*h*/\" Comment:TerminalRule\'ML_COMMENT\' Association:CONTAINER");
_builder_1.newLine();
_builder_1.append(" ");
_builder_1.append("\"\\n\\n\" Whitespace:TerminalRule\'WS\'");
_builder_1.newLine();
_builder_1.append(" ");
_builder_1.append("\"/*a*/\" Comment:TerminalRule\'ML_COMMENT\' Association:NEXT");
_builder_1.newLine();
_builder_1.append(" ");
_builder_1.append("13 \"\\n\" Whitespace:TerminalRule\'WS\'");
_builder_1.newLine();
_builder_1.append(" ");
_builder_1.append("B ValueList\'[a]\' Root");
_builder_1.newLine();
_builder_1.append("13 1 S \"a\" ValueList:name+=ID");
_builder_1.newLine();
_builder_1.append(" ");
_builder_1.append("E ValueList\'[a]\' Root");
_builder_1.newLine();
_builder_1.append("14 0 H");
_builder_1.newLine();
_builder_1.append("------------ diff 1 ------------");
_builder_1.newLine();
_builder_1.append(" ");
_builder_1.append("0 H \"/*h*/\" Comment:TerminalRule\'ML_COMMENT\' Association:CONTAINER");
_builder_1.newLine();
_builder_1.append(" ");
_builder_1.append("\"\\n\\n\" Whitespace:TerminalRule\'WS\'");
_builder_1.newLine();
_builder_1.append(" ");
_builder_1.append("\"/*81*/\" Comment:TerminalRule\'ML_COMMENT\' Association:NEXT");
_builder_1.newLine();
_builder_1.append(" ");
_builder_1.append("\"\\n\" Whitespace:TerminalRule\'WS\'");
_builder_1.newLine();
_builder_1.append(" ");
_builder_1.append("\"/*82*/\" Comment:TerminalRule\'ML_COMMENT\' Association:NEXT");
_builder_1.newLine();
_builder_1.append(" ");
_builder_1.append("21 \"\\n\" Whitespace:TerminalRule\'WS\'");
_builder_1.newLine();
_builder_1.append("21 1 S \"8\" Root:\'8\'");
_builder_1.newLine();
_builder_1.append("22 H \" \" Whitespace:TerminalRule\'WS\'");
_builder_1.newLine();
_builder_1.append(" ");
_builder_1.append("\"//8\\n\" Comment:TerminalRule\'SL_COMMENT\' Association:PREVIOUS");
_builder_1.newLine();
_builder_1.append(" ");
_builder_1.append("\"/*a*/\" Comment:TerminalRule\'ML_COMMENT\' Association:NEXT");
_builder_1.newLine();
_builder_1.append(" ");
_builder_1.append("11 \"\\n\" Whitespace:TerminalRule\'WS\'");
_builder_1.newLine();
this._regionAccessTestHelper.operator_tripleEquals(_modify, _builder_1);
}
@Test
public void testDeleteFirstRegion3() throws Exception {
StringConcatenation _builder = new StringConcatenation();
_builder.append("/*h*/");
_builder.newLine();
_builder.append("/*81*/");
_builder.newLine();
_builder.newLine();
_builder.append("/*82*/");
_builder.newLine();
_builder.append("8 //8");
_builder.newLine();
_builder.append("/*a*/");
_builder.newLine();
_builder.append("a");
_builder.newLine();
final ITextRegionAccess access = this._regionAccessTestHelper.toTextRegionAccess(_builder);
final Procedure1<ITextRegionDiffBuilder> _function = (ITextRegionDiffBuilder it) -> {
final ISemanticRegion foo = access.regionForRootEObject().getAllRegionsFor().keyword("8");
it.remove(foo);
};
ITextRegionAccess _modify = this._regionAccessTestHelper.modify(access, _function);
StringConcatenation _builder_1 = new StringConcatenation();
_builder_1.append(" ");
_builder_1.append("0 1 H \"/*h*/\" Comment:TerminalRule\'ML_COMMENT\' Association:CONTAINER");
_builder_1.newLine();
_builder_1.append(" ");
_builder_1.append("\"\\n\" Whitespace:TerminalRule\'WS\'");
_builder_1.newLine();
_builder_1.append(" ");
_builder_1.append("\"/*81*/\" Comment:TerminalRule\'ML_COMMENT\' Association:CONTAINER");
_builder_1.newLine();
_builder_1.append(" ");
_builder_1.append("\"\\n\\n\" Whitespace:TerminalRule\'WS\'");
_builder_1.newLine();
_builder_1.append(" ");
_builder_1.append("\"/*a*/\" Comment:TerminalRule\'ML_COMMENT\' Association:NEXT");
_builder_1.newLine();
_builder_1.append(" ");
_builder_1.append("20 \"\\n\" Whitespace:TerminalRule\'WS\'");
_builder_1.newLine();
_builder_1.append(" ");
_builder_1.append("B ValueList\'[a]\' Root");
_builder_1.newLine();
_builder_1.append("20 1 S \"a\" ValueList:name+=ID");
_builder_1.newLine();
_builder_1.append(" ");
_builder_1.append("E ValueList\'[a]\' Root");
_builder_1.newLine();
_builder_1.append("21 0 H");
_builder_1.newLine();
_builder_1.append("------------ diff 1 ------------");
_builder_1.newLine();
_builder_1.append(" ");
_builder_1.append("0 H \"/*h*/\" Comment:TerminalRule\'ML_COMMENT\' Association:CONTAINER");
_builder_1.newLine();
_builder_1.append(" ");
_builder_1.append("\"\\n\" Whitespace:TerminalRule\'WS\'");
_builder_1.newLine();
_builder_1.append(" ");
_builder_1.append("\"/*81*/\" Comment:TerminalRule\'ML_COMMENT\' Association:CONTAINER");
_builder_1.newLine();
_builder_1.append(" ");
_builder_1.append("\"\\n\\n\" Whitespace:TerminalRule\'WS\'");
_builder_1.newLine();
_builder_1.append(" ");
_builder_1.append("\"/*82*/\" Comment:TerminalRule\'ML_COMMENT\' Association:NEXT");
_builder_1.newLine();
_builder_1.append(" ");
_builder_1.append("21 \"\\n\" Whitespace:TerminalRule\'WS\'");
_builder_1.newLine();
_builder_1.append("21 1 S \"8\" Root:\'8\'");
_builder_1.newLine();
_builder_1.append("22 H \" \" Whitespace:TerminalRule\'WS\'");
_builder_1.newLine();
_builder_1.append(" ");
_builder_1.append("\"//8\\n\" Comment:TerminalRule\'SL_COMMENT\' Association:PREVIOUS");
_builder_1.newLine();
_builder_1.append(" ");
_builder_1.append("\"/*a*/\" Comment:TerminalRule\'ML_COMMENT\' Association:NEXT");
_builder_1.newLine();
_builder_1.append(" ");
_builder_1.append("11 \"\\n\" Whitespace:TerminalRule\'WS\'");
_builder_1.newLine();
this._regionAccessTestHelper.operator_tripleEquals(_modify, _builder_1);
}
@Test
public void testDeleteFirstRegion4() throws Exception {
StringConcatenation _builder = new StringConcatenation();
_builder.append("/*h*/");
_builder.newLine();
_builder.append("/*81*/");
_builder.newLine();
_builder.append("/*82*/");
_builder.newLine();
_builder.newLine();
_builder.append("8 //8");
_builder.newLine();
_builder.append("/*a*/");
_builder.newLine();
_builder.append("a");
_builder.newLine();
final ITextRegionAccess access = this._regionAccessTestHelper.toTextRegionAccess(_builder);
final Procedure1<ITextRegionDiffBuilder> _function = (ITextRegionDiffBuilder it) -> {
final ISemanticRegion foo = access.regionForRootEObject().getAllRegionsFor().keyword("8");
it.remove(foo);
};
ITextRegionAccess _modify = this._regionAccessTestHelper.modify(access, _function);
StringConcatenation _builder_1 = new StringConcatenation();
_builder_1.append(" ");
_builder_1.append("0 1 H \"/*h*/\" Comment:TerminalRule\'ML_COMMENT\' Association:CONTAINER");
_builder_1.newLine();
_builder_1.append(" ");
_builder_1.append("\"\\n\" Whitespace:TerminalRule\'WS\'");
_builder_1.newLine();
_builder_1.append(" ");
_builder_1.append("\"/*81*/\" Comment:TerminalRule\'ML_COMMENT\' Association:CONTAINER");
_builder_1.newLine();
_builder_1.append(" ");
_builder_1.append("\"\\n\" Whitespace:TerminalRule\'WS\'");
_builder_1.newLine();
_builder_1.append(" ");
_builder_1.append("\"/*82*/\" Comment:TerminalRule\'ML_COMMENT\' Association:CONTAINER");
_builder_1.newLine();
_builder_1.append(" ");
_builder_1.append("\"\\n\\n\" Whitespace:TerminalRule\'WS\'");
_builder_1.newLine();
_builder_1.append(" ");
_builder_1.append("\"/*a*/\" Comment:TerminalRule\'ML_COMMENT\' Association:NEXT");
_builder_1.newLine();
_builder_1.append(" ");
_builder_1.append("27 \"\\n\" Whitespace:TerminalRule\'WS\'");
_builder_1.newLine();
_builder_1.append(" ");
_builder_1.append("B ValueList\'[a]\' Root");
_builder_1.newLine();
_builder_1.append("27 1 S \"a\" ValueList:name+=ID");
_builder_1.newLine();
_builder_1.append(" ");
_builder_1.append("E ValueList\'[a]\' Root");
_builder_1.newLine();
_builder_1.append("28 0 H");
_builder_1.newLine();
_builder_1.append("------------ diff 1 ------------");
_builder_1.newLine();
_builder_1.append(" ");
_builder_1.append("0 H \"/*h*/\" Comment:TerminalRule\'ML_COMMENT\' Association:CONTAINER");
_builder_1.newLine();
_builder_1.append(" ");
_builder_1.append("\"\\n\" Whitespace:TerminalRule\'WS\'");
_builder_1.newLine();
_builder_1.append(" ");
_builder_1.append("\"/*81*/\" Comment:TerminalRule\'ML_COMMENT\' Association:CONTAINER");
_builder_1.newLine();
_builder_1.append(" ");
_builder_1.append("\"\\n\" Whitespace:TerminalRule\'WS\'");
_builder_1.newLine();
_builder_1.append(" ");
_builder_1.append("\"/*82*/\" Comment:TerminalRule\'ML_COMMENT\' Association:CONTAINER");
_builder_1.newLine();
_builder_1.append(" ");
_builder_1.append("21 \"\\n\\n\" Whitespace:TerminalRule\'WS\'");
_builder_1.newLine();
_builder_1.append("21 1 S \"8\" Root:\'8\'");
_builder_1.newLine();
_builder_1.append("22 H \" \" Whitespace:TerminalRule\'WS\'");
_builder_1.newLine();
_builder_1.append(" ");
_builder_1.append("\"//8\\n\" Comment:TerminalRule\'SL_COMMENT\' Association:PREVIOUS");
_builder_1.newLine();
_builder_1.append(" ");
_builder_1.append("\"/*a*/\" Comment:TerminalRule\'ML_COMMENT\' Association:NEXT");
_builder_1.newLine();
_builder_1.append(" ");
_builder_1.append("11 \"\\n\" Whitespace:TerminalRule\'WS\'");
_builder_1.newLine();
this._regionAccessTestHelper.operator_tripleEquals(_modify, _builder_1);
}
@Test
public void testDeleteMiddleRegion() throws Exception {
StringConcatenation _builder = new StringConcatenation();
_builder.append("8");
_builder.newLine();
_builder.append("a /*a*/ //a");
_builder.newLine();
_builder.append("/*b1*/");
_builder.newLine();
_builder.append("/*b2*/");
_builder.newLine();
_builder.append("b");
_builder.newLine();
final ITextRegionAccess access = this._regionAccessTestHelper.toTextRegionAccess(_builder);
final Procedure1<ITextRegionDiffBuilder> _function = (ITextRegionDiffBuilder it) -> {
final ISemanticRegion foo = IterableExtensions.<ISemanticRegion>head(access.regionForRootEObject().getAllRegionsFor().features(RegionaccesstestlanguagePackage.Literals.VALUE_LIST__NAME));
it.remove(foo);
};
ITextRegionAccess _modify = this._regionAccessTestHelper.modify(access, _function);
StringConcatenation _builder_1 = new StringConcatenation();
_builder_1.append(" ");
_builder_1.append("0 0 H");
_builder_1.newLine();
_builder_1.append(" ");
_builder_1.append("B ValueList\'[a, b]\' Root");
_builder_1.newLine();
_builder_1.append(" ");
_builder_1.append("0 1 S \"8\" Root:\'8\'");
_builder_1.newLine();
_builder_1.append(" ");
_builder_1.append("1 1 H \"\\n\" Whitespace:TerminalRule\'WS\'");
_builder_1.newLine();
_builder_1.append(" ");
_builder_1.append("\"/*b1*/\" Comment:TerminalRule\'ML_COMMENT\' Association:NEXT");
_builder_1.newLine();
_builder_1.append(" ");
_builder_1.append("\"\\n\" Whitespace:TerminalRule\'WS\'");
_builder_1.newLine();
_builder_1.append(" ");
_builder_1.append("\"/*b2*/\" Comment:TerminalRule\'ML_COMMENT\' Association:NEXT");
_builder_1.newLine();
_builder_1.append(" ");
_builder_1.append("15 \"\\n\" Whitespace:TerminalRule\'WS\'");
_builder_1.newLine();
_builder_1.append("16 1 S \"b\" ValueList:name+=ID");
_builder_1.newLine();
_builder_1.append(" ");
_builder_1.append("E ValueList\'[a, b]\' Root");
_builder_1.newLine();
_builder_1.append("17 0 H");
_builder_1.newLine();
_builder_1.append("------------ diff 1 ------------");
_builder_1.newLine();
_builder_1.append(" ");
_builder_1.append("1 1 H \"\\n\" Whitespace:TerminalRule\'WS\'");
_builder_1.newLine();
_builder_1.append(" ");
_builder_1.append("2 1 S \"a\" ValueList:name+=ID");
_builder_1.newLine();
_builder_1.append(" ");
_builder_1.append("3 H \" \" Whitespace:TerminalRule\'WS\'");
_builder_1.newLine();
_builder_1.append(" ");
_builder_1.append("\"/*a*/\" Comment:TerminalRule\'ML_COMMENT\' Association:PREVIOUS");
_builder_1.newLine();
_builder_1.append(" ");
_builder_1.append("\" \" Whitespace:TerminalRule\'WS\'");
_builder_1.newLine();
_builder_1.append(" ");
_builder_1.append("\"//a\\n\" Comment:TerminalRule\'SL_COMMENT\' Association:PREVIOUS");
_builder_1.newLine();
_builder_1.append(" ");
_builder_1.append("\"/*b1*/\" Comment:TerminalRule\'ML_COMMENT\' Association:NEXT");
_builder_1.newLine();
_builder_1.append(" ");
_builder_1.append("\"\\n\" Whitespace:TerminalRule\'WS\'");
_builder_1.newLine();
_builder_1.append(" ");
_builder_1.append("\"/*b2*/\" Comment:TerminalRule\'ML_COMMENT\' Association:NEXT");
_builder_1.newLine();
_builder_1.append(" ");
_builder_1.append("25 \"\\n\" Whitespace:TerminalRule\'WS\'");
_builder_1.newLine();
this._regionAccessTestHelper.operator_tripleEquals(_modify, _builder_1);
}
@Test
public void testMove() throws Exception {
StringConcatenation _builder = new StringConcatenation();
_builder.append("8//8");
_builder.newLine();
_builder.append("/*a*/");
_builder.newLine();
_builder.append("a//a");
_builder.newLine();
_builder.append("/*b*/");
_builder.newLine();
_builder.append("b//b");
_builder.newLine();
_builder.append("/*c*/");
_builder.newLine();
_builder.append("c");
_builder.newLine();
final ITextRegionAccess access = this._regionAccessTestHelper.toTextRegionAccess(_builder);
final Procedure1<ITextRegionDiffBuilder> _function = (ITextRegionDiffBuilder it) -> {
final List<ISemanticRegion> regions = access.regionForRootEObject().getAllRegionsFor().features(RegionaccesstestlanguagePackage.Literals.VALUE_LIST__NAME);
final ISemanticRegion a = regions.get(0);
final ISemanticRegion b = regions.get(1);
it.move(b.getNextHiddenRegion(), a.getPreviousHiddenRegion(), a.getNextHiddenRegion());
};
ITextRegionAccess _modify = this._regionAccessTestHelper.modify(access, _function);
StringConcatenation _builder_1 = new StringConcatenation();
_builder_1.append(" ");
_builder_1.append("0 0 H");
_builder_1.newLine();
_builder_1.append(" ");
_builder_1.append("B ValueList\'[a, b, c]\' Root");
_builder_1.newLine();
_builder_1.append(" ");
_builder_1.append("0 1 S \"8\" Root:\'8\'");
_builder_1.newLine();
_builder_1.append(" ");
_builder_1.append("1 1 H \"//8\\n\" Comment:TerminalRule\'SL_COMMENT\' Association:PREVIOUS");
_builder_1.newLine();
_builder_1.append(" ");
_builder_1.append("\"/*b*/\" Comment:TerminalRule\'ML_COMMENT\' Association:NEXT");
_builder_1.newLine();
_builder_1.append(" ");
_builder_1.append("10 \"\\n\" Whitespace:TerminalRule\'WS\'");
_builder_1.newLine();
_builder_1.append("11 1 S \"b\" ValueList:name+=ID");
_builder_1.newLine();
_builder_1.append("12 2 H \"//b\\n\" Comment:TerminalRule\'SL_COMMENT\' Association:PREVIOUS");
_builder_1.newLine();
_builder_1.append(" ");
_builder_1.append("\"/*a*/\" Comment:TerminalRule\'ML_COMMENT\' Association:NEXT");
_builder_1.newLine();
_builder_1.append(" ");
_builder_1.append("10 \"\\n\" Whitespace:TerminalRule\'WS\'");
_builder_1.newLine();
_builder_1.append("22 1 2 S \"a\" ValueList:name+=ID");
_builder_1.newLine();
_builder_1.append("23 2 H \"//a\\n\" Comment:TerminalRule\'SL_COMMENT\' Association:PREVIOUS");
_builder_1.newLine();
_builder_1.append(" ");
_builder_1.append("\"/*c*/\" Comment:TerminalRule\'ML_COMMENT\' Association:NEXT");
_builder_1.newLine();
_builder_1.append(" ");
_builder_1.append("10 \"\\n\" Whitespace:TerminalRule\'WS\'");
_builder_1.newLine();
_builder_1.append("33 1 S \"c\" ValueList:name+=ID");
_builder_1.newLine();
_builder_1.append(" ");
_builder_1.append("E ValueList\'[a, b, c]\' Root");
_builder_1.newLine();
_builder_1.append("34 0 H");
_builder_1.newLine();
_builder_1.append("------------ diff 1 ------------");
_builder_1.newLine();
_builder_1.append(" ");
_builder_1.append("1 H \"//8\\n\" Comment:TerminalRule\'SL_COMMENT\' Association:PREVIOUS");
_builder_1.newLine();
_builder_1.append(" ");
_builder_1.append("\"/*a*/\" Comment:TerminalRule\'ML_COMMENT\' Association:NEXT");
_builder_1.newLine();
_builder_1.append(" ");
_builder_1.append("10 \"\\n\" Whitespace:TerminalRule\'WS\'");
_builder_1.newLine();
_builder_1.append("11 1 S \"a\" ValueList:name+=ID");
_builder_1.newLine();
_builder_1.append("12 H \"//a\\n\" Comment:TerminalRule\'SL_COMMENT\' Association:PREVIOUS");
_builder_1.newLine();
_builder_1.append(" ");
_builder_1.append("\"/*b*/\" Comment:TerminalRule\'ML_COMMENT\' Association:NEXT");
_builder_1.newLine();
_builder_1.append(" ");
_builder_1.append("10 \"\\n\" Whitespace:TerminalRule\'WS\'");
_builder_1.newLine();
_builder_1.append("------------ diff 2 ------------");
_builder_1.newLine();
_builder_1.append("23 H \"//b\\n\" Comment:TerminalRule\'SL_COMMENT\' Association:PREVIOUS");
_builder_1.newLine();
_builder_1.append(" ");
_builder_1.append("\"/*c*/\" Comment:TerminalRule\'ML_COMMENT\' Association:NEXT");
_builder_1.newLine();
_builder_1.append(" ");
_builder_1.append("10 \"\\n\" Whitespace:TerminalRule\'WS\'");
_builder_1.newLine();
this._regionAccessTestHelper.operator_tripleEquals(_modify, _builder_1);
}
}

View file

@ -1,570 +0,0 @@
/**
* Copyright (c) 2017, 2020 TypeFox GmbH (http://www.typefox.io) 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.formatting2.regionaccess.internal;
import com.google.inject.Inject;
import java.util.List;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.xtend2.lib.StringConcatenation;
import org.eclipse.xtext.formatting2.regionaccess.IEObjectRegion;
import org.eclipse.xtext.formatting2.regionaccess.ISemanticRegion;
import org.eclipse.xtext.formatting2.regionaccess.ITextRegionAccess;
import org.eclipse.xtext.formatting2.regionaccess.ITextRegionDiffBuilder;
import org.eclipse.xtext.formatting2.regionaccess.ITextRegionExtensions;
import org.eclipse.xtext.formatting2.regionaccess.internal.regionaccesstestlanguage.Delegate;
import org.eclipse.xtext.formatting2.regionaccess.internal.regionaccesstestlanguage.Delegation;
import org.eclipse.xtext.formatting2.regionaccess.internal.regionaccesstestlanguage.PrefixedUnassigned;
import org.eclipse.xtext.formatting2.regionaccess.internal.regionaccesstestlanguage.RegionaccesstestlanguagePackage;
import org.eclipse.xtext.formatting2.regionaccess.internal.regionaccesstestlanguage.ValueList;
import org.eclipse.xtext.formatting2.regionaccess.internal.tests.RegionAccessTestLanguageInjectorProvider;
import org.eclipse.xtext.serializer.impl.Serializer;
import org.eclipse.xtext.testing.InjectWith;
import org.eclipse.xtext.testing.XtextRunner;
import org.eclipse.xtext.xbase.lib.Extension;
import org.eclipse.xtext.xbase.lib.Procedures.Procedure1;
import org.junit.Test;
import org.junit.runner.RunWith;
/**
* @author Moritz Eysholdt - Initial contribution and API
*/
@InjectWith(RegionAccessTestLanguageInjectorProvider.class)
@RunWith(XtextRunner.class)
@SuppressWarnings("all")
public class RegionAccessDiffTest {
@Inject
@Extension
private RegionAccessTestHelper _regionAccessTestHelper;
@Inject
private Serializer serializer;
@Test
public void testEmptyModification() throws Exception {
StringConcatenation _builder = new StringConcatenation();
_builder.append("1 foo");
_builder.newLine();
final ITextRegionAccess access = this._regionAccessTestHelper.toTextRegionAccess(_builder);
StringConcatenation _builder_1 = new StringConcatenation();
_builder_1.append("0 0 H");
_builder_1.newLine();
_builder_1.append(" ");
_builder_1.append("B Simple\'foo\' Root");
_builder_1.newLine();
_builder_1.append("0 1 S \"1\" Simple:\'1\'");
_builder_1.newLine();
_builder_1.append("1 1 H \" \" Whitespace:TerminalRule\'WS\'");
_builder_1.newLine();
_builder_1.append("2 3 S \"foo\" Simple:name=ID");
_builder_1.newLine();
_builder_1.append(" ");
_builder_1.append("E Simple\'foo\' Root");
_builder_1.newLine();
_builder_1.append("5 0 H");
_builder_1.newLine();
this._regionAccessTestHelper.operator_tripleEquals(access, _builder_1);
final Procedure1<ITextRegionDiffBuilder> _function = (ITextRegionDiffBuilder it) -> {
};
ITextRegionAccess _modify = this._regionAccessTestHelper.modify(access, _function);
StringConcatenation _builder_2 = new StringConcatenation();
_builder_2.append("0 0 H");
_builder_2.newLine();
_builder_2.append(" ");
_builder_2.append("B Simple\'foo\' Root");
_builder_2.newLine();
_builder_2.append("0 1 S \"1\" Simple:\'1\'");
_builder_2.newLine();
_builder_2.append("1 1 H \" \" Whitespace:TerminalRule\'WS\'");
_builder_2.newLine();
_builder_2.append("2 3 S \"foo\" Simple:name=ID");
_builder_2.newLine();
_builder_2.append(" ");
_builder_2.append("E Simple\'foo\' Root");
_builder_2.newLine();
_builder_2.append("5 0 H");
_builder_2.newLine();
this._regionAccessTestHelper.operator_tripleEquals(_modify, _builder_2);
}
@Test
public void testSingleSemanticToken() throws Exception {
StringConcatenation _builder = new StringConcatenation();
_builder.append("1 foo");
_builder.newLine();
final ITextRegionAccess access = this._regionAccessTestHelper.toTextRegionAccess(_builder);
final Procedure1<ITextRegionDiffBuilder> _function = (ITextRegionDiffBuilder it) -> {
@Extension
final ITextRegionExtensions ext = access.getExtensions();
final EObject root = access.regionForRootEObject().getSemanticElement();
final ISemanticRegion foo = ext.allRegionsFor(root).feature(RegionaccesstestlanguagePackage.Literals.SIMPLE__NAME);
it.replace(foo, "baaar");
};
ITextRegionAccess _modify = this._regionAccessTestHelper.modify(access, _function);
StringConcatenation _builder_1 = new StringConcatenation();
_builder_1.append("0 0 H");
_builder_1.newLine();
_builder_1.append(" ");
_builder_1.append("B Simple\'foo\' Root");
_builder_1.newLine();
_builder_1.append("0 1 S \"1\" Simple:\'1\'");
_builder_1.newLine();
_builder_1.append("1 1 H \" \" Whitespace:TerminalRule\'WS\'");
_builder_1.newLine();
_builder_1.append("2 5 1 S \"baaar\" Simple:name=ID");
_builder_1.newLine();
_builder_1.append(" ");
_builder_1.append("E Simple\'foo\' Root");
_builder_1.newLine();
_builder_1.append("7 0 H");
_builder_1.newLine();
_builder_1.append("------------ diff 1 ------------");
_builder_1.newLine();
_builder_1.append("2 3 S \"foo\" Simple:name=ID");
_builder_1.newLine();
this._regionAccessTestHelper.operator_tripleEquals(_modify, _builder_1);
}
@Test
public void testSerializeChildObject() throws Exception {
StringConcatenation _builder = new StringConcatenation();
_builder.append("2 foo");
_builder.newLine();
final ITextRegionAccess access = this._regionAccessTestHelper.toTextRegionAccess(_builder);
final Procedure1<ITextRegionDiffBuilder> _function = (ITextRegionDiffBuilder it) -> {
EObject _semanticElement = access.regionForRootEObject().getSemanticElement();
final Delegate child = ((Delegation) _semanticElement).getDelegate();
final IEObjectRegion childRegion = access.regionForEObject(child);
child.setName("baaaz");
final ITextRegionAccess textRegions = this.serializer.serializeToRegions(child);
it.replace(childRegion.getPreviousHiddenRegion(), childRegion.getNextHiddenRegion(), textRegions);
};
ITextRegionAccess _modify = this._regionAccessTestHelper.modify(access, _function);
StringConcatenation _builder_1 = new StringConcatenation();
_builder_1.append("0 0 H");
_builder_1.newLine();
_builder_1.append(" ");
_builder_1.append("B Delegation Root");
_builder_1.newLine();
_builder_1.append("0 1 S \"2\" Delegation:\'2\'");
_builder_1.newLine();
_builder_1.append("1 1 1 H \" \" Whitespace:TerminalRule\'WS\'");
_builder_1.newLine();
_builder_1.append(" ");
_builder_1.append("B Delegate\'baaaz\' Delegate path:Delegation/delegate");
_builder_1.newLine();
_builder_1.append("2 5 1 S \"baaaz\" Delegate:name=ID");
_builder_1.newLine();
_builder_1.append(" ");
_builder_1.append("E Delegate\'baaaz\' Delegate path:Delegation/delegate");
_builder_1.newLine();
_builder_1.append(" ");
_builder_1.append("E Delegation Root");
_builder_1.newLine();
_builder_1.append("7 0 1 H");
_builder_1.newLine();
_builder_1.append("------------ diff 1 ------------");
_builder_1.newLine();
_builder_1.append("1 1 H \" \" Whitespace:TerminalRule\'WS\'");
_builder_1.newLine();
_builder_1.append("2 3 S \"foo\" Delegate:name=ID");
_builder_1.newLine();
_builder_1.append("5 0 H");
_builder_1.newLine();
this._regionAccessTestHelper.operator_tripleEquals(_modify, _builder_1);
}
@Test
public void testSerializeRootObject() throws Exception {
StringConcatenation _builder = new StringConcatenation();
_builder.append("3 foo");
_builder.newLine();
final ITextRegionAccess access = this._regionAccessTestHelper.toTextRegionAccess(_builder);
final Procedure1<ITextRegionDiffBuilder> _function = (ITextRegionDiffBuilder it) -> {
final IEObjectRegion root = access.regionForRootEObject();
EObject _semanticElement = root.getSemanticElement();
final Delegate rootObj = ((Delegate) _semanticElement);
rootObj.setName("baaaz");
final ITextRegionAccess textRegions = this.serializer.serializeToRegions(rootObj);
it.replace(root.getPreviousHiddenRegion(), root.getNextHiddenRegion(), textRegions);
};
ITextRegionAccess _modify = this._regionAccessTestHelper.modify(access, _function);
StringConcatenation _builder_1 = new StringConcatenation();
_builder_1.append("0 0 1 H");
_builder_1.newLine();
_builder_1.append(" ");
_builder_1.append("B Delegate\'baaaz\' Root");
_builder_1.newLine();
_builder_1.append("0 1 1 S \"3\" Unassigned:\'3\'");
_builder_1.newLine();
_builder_1.append("1 1 1 H \" \" Whitespace:TerminalRule\'WS\'");
_builder_1.newLine();
_builder_1.append("2 5 1 S \"baaaz\" Delegate:name=ID");
_builder_1.newLine();
_builder_1.append(" ");
_builder_1.append("E Delegate\'baaaz\' Root");
_builder_1.newLine();
_builder_1.append("7 0 1 H");
_builder_1.newLine();
_builder_1.append("------------ diff 1 ------------");
_builder_1.newLine();
_builder_1.append("0 0 H");
_builder_1.newLine();
_builder_1.append("0 1 S \"3\" Unassigned:\'3\'");
_builder_1.newLine();
_builder_1.append("1 1 H \" \" Whitespace:TerminalRule\'WS\'");
_builder_1.newLine();
_builder_1.append("2 3 S \"foo\" Delegate:name=ID");
_builder_1.newLine();
_builder_1.append("5 0 H");
_builder_1.newLine();
this._regionAccessTestHelper.operator_tripleEquals(_modify, _builder_1);
}
@Test
public void testDeleteOne() throws Exception {
StringConcatenation _builder = new StringConcatenation();
_builder.append("4/*1*/prefix/*2*/foo");
_builder.newLine();
final ITextRegionAccess access = this._regionAccessTestHelper.toTextRegionAccess(_builder);
final Procedure1<ITextRegionDiffBuilder> _function = (ITextRegionDiffBuilder it) -> {
@Extension
final ITextRegionExtensions ext = access.getExtensions();
EObject _semanticElement = access.regionForRootEObject().getSemanticElement();
final PrefixedUnassigned rootObj = ((PrefixedUnassigned) _semanticElement);
final ISemanticRegion prefix = ext.regionFor(rootObj.getDelegate()).keyword("prefix");
it.remove(prefix);
};
ITextRegionAccess _modify = this._regionAccessTestHelper.modify(access, _function);
StringConcatenation _builder_1 = new StringConcatenation();
_builder_1.append(" ");
_builder_1.append("0 0 H");
_builder_1.newLine();
_builder_1.append(" ");
_builder_1.append("B PrefixedUnassigned Root");
_builder_1.newLine();
_builder_1.append(" ");
_builder_1.append("0 1 S \"4\" PrefixedUnassigned:\'4\'");
_builder_1.newLine();
_builder_1.append(" ");
_builder_1.append("1 1 H \"/*1*/\" Comment:TerminalRule\'ML_COMMENT\' Association:CONTAINER");
_builder_1.newLine();
_builder_1.append(" ");
_builder_1.append("10 \"/*2*/\" Comment:TerminalRule\'ML_COMMENT\' Association:CONTAINER");
_builder_1.newLine();
_builder_1.append(" ");
_builder_1.append("B Delegate\'foo\' PrefixedUnassigned:delegate=PrefixedDelegate path:PrefixedUnassigned/delegate");
_builder_1.newLine();
_builder_1.append("11 3 S \"foo\" Delegate:name=ID");
_builder_1.newLine();
_builder_1.append(" ");
_builder_1.append("E Delegate\'foo\' PrefixedUnassigned:delegate=PrefixedDelegate path:PrefixedUnassigned/delegate");
_builder_1.newLine();
_builder_1.append(" ");
_builder_1.append("E PrefixedUnassigned Root");
_builder_1.newLine();
_builder_1.append("14 0 H");
_builder_1.newLine();
_builder_1.append("------------ diff 1 ------------");
_builder_1.newLine();
_builder_1.append(" ");
_builder_1.append("1 5 H \"/*1*/\" Comment:TerminalRule\'ML_COMMENT\' Association:CONTAINER");
_builder_1.newLine();
_builder_1.append(" ");
_builder_1.append("6 6 S \"prefix\" PrefixedDelegate:\'prefix\'");
_builder_1.newLine();
_builder_1.append("12 5 H \"/*2*/\" Comment:TerminalRule\'ML_COMMENT\' Association:CONTAINER");
_builder_1.newLine();
this._regionAccessTestHelper.operator_tripleEquals(_modify, _builder_1);
}
@Test
public void testDeleteTwo() throws Exception {
StringConcatenation _builder = new StringConcatenation();
_builder.append("4/*1*/prefix/*2*/foo/*3*/");
_builder.newLine();
final ITextRegionAccess access = this._regionAccessTestHelper.toTextRegionAccess(_builder);
final Procedure1<ITextRegionDiffBuilder> _function = (ITextRegionDiffBuilder it) -> {
@Extension
final ITextRegionExtensions ext = access.getExtensions();
EObject _semanticElement = access.regionForRootEObject().getSemanticElement();
final PrefixedUnassigned rootObj = ((PrefixedUnassigned) _semanticElement);
final ISemanticRegion prefix = ext.regionFor(rootObj.getDelegate()).keyword("prefix");
final ISemanticRegion foo = ext.regionFor(rootObj.getDelegate()).feature(RegionaccesstestlanguagePackage.Literals.DELEGATE__NAME);
it.remove(prefix.getPreviousHiddenRegion(), foo.getNextHiddenRegion());
};
ITextRegionAccess _modify = this._regionAccessTestHelper.modify(access, _function);
StringConcatenation _builder_1 = new StringConcatenation();
_builder_1.append(" ");
_builder_1.append("0 0 H");
_builder_1.newLine();
_builder_1.append(" ");
_builder_1.append("B PrefixedUnassigned Root");
_builder_1.newLine();
_builder_1.append(" ");
_builder_1.append("0 1 S \"4\" PrefixedUnassigned:\'4\'");
_builder_1.newLine();
_builder_1.append(" ");
_builder_1.append("E PrefixedUnassigned Root");
_builder_1.newLine();
_builder_1.append(" ");
_builder_1.append("1 1 H \"/*1*/\" Comment:TerminalRule\'ML_COMMENT\' Association:CONTAINER");
_builder_1.newLine();
_builder_1.append(" ");
_builder_1.append("10 \"/*3*/\" Comment:TerminalRule\'ML_COMMENT\' Association:CONTAINER");
_builder_1.newLine();
_builder_1.append("------------ diff 1 ------------");
_builder_1.newLine();
_builder_1.append(" ");
_builder_1.append("1 5 H \"/*1*/\" Comment:TerminalRule\'ML_COMMENT\' Association:CONTAINER");
_builder_1.newLine();
_builder_1.append(" ");
_builder_1.append("6 6 S \"prefix\" PrefixedDelegate:\'prefix\'");
_builder_1.newLine();
_builder_1.append("12 5 H \"/*2*/\" Comment:TerminalRule\'ML_COMMENT\' Association:CONTAINER");
_builder_1.newLine();
_builder_1.append("17 3 S \"foo\" Delegate:name=ID");
_builder_1.newLine();
_builder_1.append("20 5 H \"/*3*/\" Comment:TerminalRule\'ML_COMMENT\' Association:CONTAINER");
_builder_1.newLine();
this._regionAccessTestHelper.operator_tripleEquals(_modify, _builder_1);
}
@Test
public void testInsertInsertReplace() throws Exception {
StringConcatenation _builder = new StringConcatenation();
_builder.append("8 a");
_builder.newLine();
final ITextRegionAccess access = this._regionAccessTestHelper.toTextRegionAccess(_builder);
final Procedure1<ITextRegionDiffBuilder> _function = (ITextRegionDiffBuilder it) -> {
@Extension
final ITextRegionExtensions ext = access.getExtensions();
EObject _semanticElement = access.regionForRootEObject().getSemanticElement();
final ValueList rootObj = ((ValueList) _semanticElement);
final ISemanticRegion a = ext.regionFor(rootObj).keyword("8").getNextSemanticRegion();
it.replace(a.getNextHiddenRegion(), a.getNextHiddenRegion(), a.getPreviousHiddenRegion(), a.getNextHiddenRegion());
it.replace(a.getNextHiddenRegion(), a.getNextHiddenRegion(), a.getPreviousHiddenRegion(), a.getNextHiddenRegion());
it.replace(a, "new");
};
ITextRegionAccess _modify = this._regionAccessTestHelper.modify(access, _function);
StringConcatenation _builder_1 = new StringConcatenation();
_builder_1.append(" ");
_builder_1.append("0 0 H");
_builder_1.newLine();
_builder_1.append(" ");
_builder_1.append("B ValueList\'[a]\' Root");
_builder_1.newLine();
_builder_1.append(" ");
_builder_1.append("0 1 S \"8\" Root:\'8\'");
_builder_1.newLine();
_builder_1.append(" ");
_builder_1.append("1 1 H \" \" Whitespace:TerminalRule\'WS\'");
_builder_1.newLine();
_builder_1.append(" ");
_builder_1.append("2 3 2 S \"new\" ValueList:name+=ID");
_builder_1.newLine();
_builder_1.append(" ");
_builder_1.append("5 0 2 H");
_builder_1.newLine();
_builder_1.append(" ");
_builder_1.append("5 3 2 S \"new\" ValueList:name+=ID");
_builder_1.newLine();
_builder_1.append(" ");
_builder_1.append("8 0 2 H");
_builder_1.newLine();
_builder_1.append(" ");
_builder_1.append("8 3 2 S \"new\" ValueList:name+=ID");
_builder_1.newLine();
_builder_1.append(" ");
_builder_1.append("E ValueList\'[a]\' Root");
_builder_1.newLine();
_builder_1.append("11 0 2 H");
_builder_1.newLine();
_builder_1.append("------------ diff 1 ------------");
_builder_1.newLine();
_builder_1.append(" ");
_builder_1.append("2 1 S \"a\" ValueList:name+=ID");
_builder_1.newLine();
_builder_1.append("------------ diff 2 ------------");
_builder_1.newLine();
_builder_1.append(" ");
_builder_1.append("2 1 S \"a\" ValueList:name+=ID");
_builder_1.newLine();
_builder_1.append(" ");
_builder_1.append("3 0 H");
_builder_1.newLine();
this._regionAccessTestHelper.operator_tripleEquals(_modify, _builder_1);
}
@Test
public void testInsertReplaceReplace() throws Exception {
StringConcatenation _builder = new StringConcatenation();
_builder.append("8 a");
_builder.newLine();
final ITextRegionAccess access = this._regionAccessTestHelper.toTextRegionAccess(_builder);
final Procedure1<ITextRegionDiffBuilder> _function = (ITextRegionDiffBuilder it) -> {
@Extension
final ITextRegionExtensions ext = access.getExtensions();
EObject _semanticElement = access.regionForRootEObject().getSemanticElement();
final ValueList rootObj = ((ValueList) _semanticElement);
final ISemanticRegion a = ext.regionFor(rootObj).keyword("8").getNextSemanticRegion();
it.replace(a, "b");
it.replace(a, "c");
};
ITextRegionAccess _modify = this._regionAccessTestHelper.modify(access, _function);
StringConcatenation _builder_1 = new StringConcatenation();
_builder_1.append("0 0 H");
_builder_1.newLine();
_builder_1.append(" ");
_builder_1.append("B ValueList\'[a]\' Root");
_builder_1.newLine();
_builder_1.append("0 1 S \"8\" Root:\'8\'");
_builder_1.newLine();
_builder_1.append("1 1 H \" \" Whitespace:TerminalRule\'WS\'");
_builder_1.newLine();
_builder_1.append("2 1 1 S \"c\" ValueList:name+=ID");
_builder_1.newLine();
_builder_1.append(" ");
_builder_1.append("E ValueList\'[a]\' Root");
_builder_1.newLine();
_builder_1.append("3 0 H");
_builder_1.newLine();
_builder_1.append("------------ diff 1 ------------");
_builder_1.newLine();
_builder_1.append("2 1 S \"a\" ValueList:name+=ID");
_builder_1.newLine();
this._regionAccessTestHelper.operator_tripleEquals(_modify, _builder_1);
}
@Test
public void testInsertBeforeComment() throws Exception {
StringConcatenation _builder = new StringConcatenation();
_builder.append("8");
_builder.newLine();
_builder.append("/**/");
_builder.newLine();
_builder.append("a b");
_builder.newLine();
final ITextRegionAccess access = this._regionAccessTestHelper.toTextRegionAccess(_builder);
final Procedure1<ITextRegionDiffBuilder> _function = (ITextRegionDiffBuilder it) -> {
@Extension
final ITextRegionExtensions ext = access.getExtensions();
EObject _semanticElement = access.regionForRootEObject().getSemanticElement();
final ValueList rootObj = ((ValueList) _semanticElement);
final ISemanticRegion a = ext.regionFor(rootObj).keyword("8").getNextSemanticRegion();
final ISemanticRegion b = a.getNextSemanticRegion();
it.replace(a.getPreviousHiddenRegion(), a.getPreviousHiddenRegion(), b.getPreviousHiddenRegion(), b.getNextHiddenRegion());
};
ITextRegionAccess _modify = this._regionAccessTestHelper.modify(access, _function);
StringConcatenation _builder_1 = new StringConcatenation();
_builder_1.append(" ");
_builder_1.append("0 0 H");
_builder_1.newLine();
_builder_1.append(" ");
_builder_1.append("B ValueList\'[a, b]\' Root");
_builder_1.newLine();
_builder_1.append(" ");
_builder_1.append("0 1 S \"8\" Root:\'8\'");
_builder_1.newLine();
_builder_1.append(" ");
_builder_1.append("1 1 1 H \"\\n\" Whitespace:TerminalRule\'WS\'");
_builder_1.newLine();
_builder_1.append(" ");
_builder_1.append("2 1 1 S \"b\" ValueList:name+=ID");
_builder_1.newLine();
_builder_1.append(" ");
_builder_1.append("3 1 H \"/**/\" Comment:TerminalRule\'ML_COMMENT\' Association:PREVIOUS");
_builder_1.newLine();
_builder_1.append(" ");
_builder_1.append("5 \"\\n\" Whitespace:TerminalRule\'WS\'");
_builder_1.newLine();
_builder_1.append(" ");
_builder_1.append("8 1 S \"a\" ValueList:name+=ID");
_builder_1.newLine();
_builder_1.append(" ");
_builder_1.append("9 1 H \" \" Whitespace:TerminalRule\'WS\'");
_builder_1.newLine();
_builder_1.append("10 1 S \"b\" ValueList:name+=ID");
_builder_1.newLine();
_builder_1.append(" ");
_builder_1.append("E ValueList\'[a, b]\' Root");
_builder_1.newLine();
_builder_1.append("11 0 H");
_builder_1.newLine();
_builder_1.append("------------ diff 1 ------------");
_builder_1.newLine();
_builder_1.append(" ");
_builder_1.append("1 H \"\\n\" Whitespace:TerminalRule\'WS\'");
_builder_1.newLine();
_builder_1.append(" ");
_builder_1.append("\"/**/\" Comment:TerminalRule\'ML_COMMENT\' Association:NEXT");
_builder_1.newLine();
_builder_1.append(" ");
_builder_1.append("6 \"\\n\" Whitespace:TerminalRule\'WS\'");
_builder_1.newLine();
this._regionAccessTestHelper.operator_tripleEquals(_modify, _builder_1);
}
@Test
public void testMove() throws Exception {
StringConcatenation _builder = new StringConcatenation();
_builder.append("8 a b c");
_builder.newLine();
final ITextRegionAccess access = this._regionAccessTestHelper.toTextRegionAccess(_builder);
final Procedure1<ITextRegionDiffBuilder> _function = (ITextRegionDiffBuilder it) -> {
final List<ISemanticRegion> regions = access.regionForRootEObject().getAllRegionsFor().features(RegionaccesstestlanguagePackage.Literals.VALUE_LIST__NAME);
final ISemanticRegion a = regions.get(0);
final ISemanticRegion b = regions.get(1);
it.move(b.getNextHiddenRegion(), a.getPreviousHiddenRegion(), a.getNextHiddenRegion());
};
ITextRegionAccess _modify = this._regionAccessTestHelper.modify(access, _function);
StringConcatenation _builder_1 = new StringConcatenation();
_builder_1.append("0 0 H");
_builder_1.newLine();
_builder_1.append(" ");
_builder_1.append("B ValueList\'[a, b, c]\' Root");
_builder_1.newLine();
_builder_1.append("0 1 S \"8\" Root:\'8\'");
_builder_1.newLine();
_builder_1.append("1 1 H \" \" Whitespace:TerminalRule\'WS\'");
_builder_1.newLine();
_builder_1.append(" ");
_builder_1.append("2 \" \" Whitespace:TerminalRule\'WS\'");
_builder_1.newLine();
_builder_1.append("3 1 S \"b\" ValueList:name+=ID");
_builder_1.newLine();
_builder_1.append("4 1 2 H \" \" Whitespace:TerminalRule\'WS\'");
_builder_1.newLine();
_builder_1.append("5 1 2 S \"a\" ValueList:name+=ID");
_builder_1.newLine();
_builder_1.append("6 0 2 H");
_builder_1.newLine();
_builder_1.append("6 1 S \"c\" ValueList:name+=ID");
_builder_1.newLine();
_builder_1.append(" ");
_builder_1.append("E ValueList\'[a, b, c]\' Root");
_builder_1.newLine();
_builder_1.append("7 0 H");
_builder_1.newLine();
_builder_1.append("------------ diff 1 ------------");
_builder_1.newLine();
_builder_1.append("1 1 H \" \" Whitespace:TerminalRule\'WS\'");
_builder_1.newLine();
_builder_1.append("2 1 S \"a\" ValueList:name+=ID");
_builder_1.newLine();
_builder_1.append("3 1 H \" \" Whitespace:TerminalRule\'WS\'");
_builder_1.newLine();
_builder_1.append("------------ diff 2 ------------");
_builder_1.newLine();
_builder_1.append("5 1 H \" \" Whitespace:TerminalRule\'WS\'");
_builder_1.newLine();
_builder_1.append("6 1 S \"c\" ValueList:name+=ID");
_builder_1.newLine();
this._regionAccessTestHelper.operator_tripleEquals(_modify, _builder_1);
}
}