Merge pull request #1595 from eclipse/cd_moreTestX2J

[eclipse/xtext#1837] converted xtend 2 java
This commit is contained in:
Christian Dietrich 2020-10-23 09:38:29 +02:00 committed by GitHub
commit be53e1d841
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
60 changed files with 2534 additions and 5644 deletions

View file

@ -0,0 +1,40 @@
/**
* 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.ide.tests.server;
import java.util.List;
import org.eclipse.lsp4j.CodeLens;
import org.eclipse.lsp4j.Position;
import org.junit.Assert;
import org.junit.Test;
import com.google.common.collect.Iterables;
/**
* @author Sven Efftinge - Initial contribution and API
*/
public class CodeLensTest extends AbstractTestLangLanguageServerTest {
@Test
public void testCodeLens() {
testCodeLens((TestCodeLensConfiguration cfg) -> {
String model =
"type Foo {}\n" +
"type Bar {\n" +
" Foo foo\n" +
"}";
cfg.setModel(model);
cfg.setAssertCodeLenses((List<? extends CodeLens> result) -> {
CodeLens first = Iterables.getFirst(result, null);
assertEquals("Do Awesome Stuff(RESOLVED)", first.getCommand().getTitle());
Assert.assertEquals(1, ((Position) first.getData()).getLine());
});
});
}
}

View file

@ -1,34 +0,0 @@
/*******************************************************************************
* Copyright (c) 2017 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.ide.tests.server
import org.eclipse.lsp4j.Position
import org.junit.Assert
import org.junit.Test
/**
* @author Sven Efftinge - Initial contribution and API
*/
class CodeLensTest extends AbstractTestLangLanguageServerTest {
@Test def void testCodeLens() {
testCodeLens [
model = '''
type Foo {}
type Bar {
Foo foo
}
'''
assertCodeLenses = [
assertEquals("Do Awesome Stuff(RESOLVED)", head.command.title)
Assert.assertEquals(1, (head.data as Position).line)
]
]
}
}

View file

@ -0,0 +1,110 @@
/**
* Copyright (c) 2018, 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.ide.tests.server;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.function.Consumer;
import org.eclipse.lsp4j.ClientCapabilities;
import org.eclipse.lsp4j.ExecuteCommandCapabilities;
import org.eclipse.lsp4j.ExecuteCommandParams;
import org.eclipse.lsp4j.InitializeParams;
import org.eclipse.lsp4j.WorkspaceClientCapabilities;
import org.eclipse.xtext.xbase.lib.Procedures.Procedure1;
import org.junit.Assert;
import org.junit.Test;
/**
* @author Christian Dietrich - Initial contribution and API
*/
public class CommandServiceTest extends AbstractTestLangLanguageServerTest {
public static class TestExecuteCommandConfiguration {
private String command = "";
private List<Object> args = new ArrayList<Object>();
private Consumer<Object> assertCommandResult = null;
public String getCommand() {
return command;
}
public void setCommand(String command) {
this.command = command;
}
public List<Object> getArgs() {
return args;
}
public void setArgs(List<Object> args) {
this.args = args;
}
public Consumer<Object> getAssertCommandResult() {
return assertCommandResult;
}
public void setAssertCommandResult(Consumer<Object> assertCommandResult) {
this.assertCommandResult = assertCommandResult;
}
}
protected void testExecuteCommand(Procedure1<? super TestExecuteCommandConfiguration> configurator)
throws Exception {
TestExecuteCommandConfiguration configuration = new TestExecuteCommandConfiguration();
configurator.apply(configuration);
String command = configuration.command;
List<Object> args = configuration.args;
CompletableFuture<Object> result = languageServer.executeCommand(new ExecuteCommandParams(command, args));
if (configuration.assertCommandResult != null) {
Object value = result.get();
configuration.assertCommandResult.accept(value);
}
}
@Test
public void testExecute() throws Exception {
initialize((InitializeParams it) -> {
ClientCapabilities clientCapabilities = new ClientCapabilities();
WorkspaceClientCapabilities workspaceClientCapabilities = new WorkspaceClientCapabilities();
workspaceClientCapabilities.setExecuteCommand(new ExecuteCommandCapabilities(true));
clientCapabilities.setWorkspace(workspaceClientCapabilities);
it.setCapabilities(clientCapabilities);
});
testExecuteCommand((TestExecuteCommandConfiguration cfg) -> {
cfg.command = "testlang.a";
cfg.assertCommandResult = (Object o) -> {
if (o instanceof String) {
assertEquals("a", (String) o);
} else {
Assert.fail("no string");
}
};
});
testExecuteCommand((TestExecuteCommandConfiguration cfg) -> {
cfg.command = "testlang.b";
cfg.assertCommandResult = (Object o) -> {
if (o instanceof String) {
assertEquals("b", (String) o);
} else {
Assert.fail("no string");
}
};
});
testExecuteCommand((TestExecuteCommandConfiguration cfg) -> {
cfg.command = "doesnotexist.c";
cfg.assertCommandResult = (Object o) -> {
Assert.assertNull(o);
};
});
}
}

View file

@ -1,85 +0,0 @@
/*******************************************************************************
* Copyright (c) 2018 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.ide.tests.server
import java.util.ArrayList
import java.util.List
import java.util.function.Consumer
import org.eclipse.lsp4j.ClientCapabilities
import org.eclipse.lsp4j.ExecuteCommandCapabilities
import org.eclipse.lsp4j.ExecuteCommandParams
import org.eclipse.lsp4j.WorkspaceClientCapabilities
import org.eclipse.xtend.lib.annotations.Accessors
import static org.junit.Assert.*
import org.junit.Test
/**
* @author Christian Dietrich - Initial contribution and API
*/
class CommandServiceTest extends AbstractTestLangLanguageServerTest {
@Accessors static class TestExecuteCommandConfiguration {
String command = ''
List<Object> args = new ArrayList
Consumer<Object> assertCommandResult= null
}
protected def void testExecuteCommand((TestExecuteCommandConfiguration)=>void configurator) {
val extension configuration = new TestExecuteCommandConfiguration
configurator.apply(configuration)
val command = configuration.command
val args = configuration.args
val result = languageServer.executeCommand(new ExecuteCommandParams(command, args))
if (configuration.assertCommandResult !== null) {
val value = result.get
configuration.assertCommandResult.accept(value)
}
}
@Test
def void testExecute() {
initialize[
capabilities = new ClientCapabilities => [
workspace = new WorkspaceClientCapabilities => [
executeCommand = new ExecuteCommandCapabilities => [
dynamicRegistration = true
]
]
]
]
testExecuteCommand [
command = "testlang.a"
assertCommandResult = [
if (it instanceof String) {
assertEquals("a", it)
} else {
fail("no string")
}
]
]
testExecuteCommand [
command = "testlang.b"
assertCommandResult = [
if (it instanceof String) {
assertEquals("b", it)
} else {
fail("no string")
}
]
]
testExecuteCommand [
command = "doesnotexist.c"
assertCommandResult = [
assertNull(it)
]
]
}
}

View file

@ -0,0 +1,32 @@
/**
* Copyright (c) 2016, 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.ide.tests.server;
import org.eclipse.xtext.testing.DefinitionTestConfiguration;
import org.junit.Test;
/**
* @author kosyakov - Initial contribution and API
*/
public class DefinitionTest extends AbstractTestLangLanguageServerTest {
@Test
public void testDefinition_01() {
testDefinition((DefinitionTestConfiguration cfg) -> {
String model =
"type Foo {}\n" +
"type Bar {\n" +
" Foo foo\n" +
"}";
cfg.setModel(model);
cfg.setLine(2);
cfg.setColumn(3);
cfg.setExpectedDefinitions("MyModel.testlang [[0, 5] .. [0, 8]]\n");
});
}
}

View file

@ -1,35 +0,0 @@
/*******************************************************************************
* Copyright (c) 2016 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.ide.tests.server
import org.junit.Test
/**
* @author kosyakov - Initial contribution and API
*/
class DefinitionTest extends AbstractTestLangLanguageServerTest {
@Test
def void testDefinition_01() {
testDefinition[
model = '''
type Foo {}
type Bar {
Foo foo
}
'''
line = 2
column = 3
expectedDefinitions = '''
MyModel.testlang [[0, 5] .. [0, 8]]
'''
]
}
}

View file

@ -0,0 +1,142 @@
/**
* Copyright (c) 2016, 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.ide.tests.server;
import org.eclipse.lsp4j.DocumentHighlight;
import org.eclipse.lsp4j.DocumentHighlightKind;
import org.eclipse.xtext.ide.server.occurrences.IDocumentHighlightService;
import org.eclipse.xtext.testing.DocumentHighlightConfiguration;
import org.eclipse.xtext.xbase.lib.Procedures.Procedure1;
import org.junit.Test;
/**
* Class for testing the {@link DocumentHighlightService document highlight
* service} behavior through the language server.
*
* <p>
* The string representation of on single {@link DocumentHighlight highlight}
* instance is represented with the below pattern:
*
* <pre>
* R|W|T [{d}+, {d}+] .. [{d}+, {d}+]
* </pre>
*
* where the first character describes the {@link DocumentHighlightKind kind} of
* the document highlight. If missing, then the value is {@code NaN}. The values
* between the first square brackets are the start {@link Position#getLine()
* line} and the (zero-based) {@link Position#getCharacter() character offset}
* in the line. The second square brackets contains the end position of the
* selection and described with the same semantics as the first start range.
* Multiple highlight instances are separated by the {@code |} ("pipe")
* character.
*
* @author akos.kitta - Initial contribution and API
*
* @see DocumentHighlight
* @see IDocumentHighlightService
*/
public class DocumentHighlightTest extends AbstractTestLangLanguageServerTest {
@Test
public void singleLineNoOccurrences_SelectionBeforeWriteScfgeMethodName() {
testDocumentHighlight((DocumentHighlightConfiguration cfg) -> {
cfg.setModel("type A { op foo() { } }");
cfg.setColumn("type A { op".length());
cfg.setExpectedDocumentHighlight("");
});
}
@Test
public void singleLineNoOccurrences_SelectionAfterWriteSiteMethodName() {
testDocumentHighlight((DocumentHighlightConfiguration cfg) -> {
cfg.setModel("type A { op foo() { } }");
cfg.setColumn("type A { op foo(".length());
cfg.setExpectedDocumentHighlight("");
});
}
@Test
public void singleLineSingleOccurrence() {
testDocumentHighlight((DocumentHighlightConfiguration cfg) -> {
cfg.setModel("type A { op foo() { } }");
cfg.setColumn("type A { op fo".length());
cfg.setExpectedDocumentHighlight("W [[0, 12] .. [0, 15]]");
});
}
@Test
public void singleLineSingleOccurrenceWithVariable() {
testDocumentHighlight((DocumentHighlightConfiguration cfg) -> {
cfg.setModel("type A { int foo op foo() { } }");
cfg.setColumn("type A { int fo".length());
cfg.setExpectedDocumentHighlight("W [[0, 13] .. [0, 16]]");
});
}
@Test
public void singleLineSingleOccurrenceWithMultipleTypes() {
testDocumentHighlight((DocumentHighlightConfiguration cfg) -> {
cfg.setModel("type A { op foo() { } } type B { op foo() { } }");
cfg.setColumn("type A { op fo".length());
cfg.setExpectedDocumentHighlight("W [[0, 12] .. [0, 15]]");
});
}
@Test
public void singleLineMultipleOccurrences_SelectionOnReadSite() {
testDocumentHighlight((DocumentHighlightConfiguration cfg) -> {
cfg.setModel("type A { op foo() { } op bar() { foo(10) } }");
cfg.setLine(0);
cfg.setColumn("type A { op foo() { } op bar() { fo".length());
cfg.setExpectedDocumentHighlight("W [[0, 12] .. [0, 15]] | R [[0, 33] .. [0, 36]]");
});
}
@Test
public void singleLineMultipleOccurrences_SelectionOnWriteSite() {
testDocumentHighlight((DocumentHighlightConfiguration cfg) -> {
cfg.setModel("type A { op foo() { } op bar() { foo(10) } }");
cfg.setLine(0);
cfg.setColumn("type A { op fo".length());
cfg.setExpectedDocumentHighlight("W [[0, 12] .. [0, 15]] | R [[0, 33] .. [0, 36]]");
});
}
@Test
public void multipleLinesMultipleOccurrences_WithHorizontalTabs() {
testDocumentHighlight((Procedure1<DocumentHighlightConfiguration>) (DocumentHighlightConfiguration cfg) -> {
String model =
"type A {\n" +
" op foo() { }\n" +
" op bar() {\n" +
" foo(10)\n" +
" }\n}";
cfg.setModel(model);
cfg.setLine(1);
cfg.setColumn("\top fo".length());
cfg.setExpectedDocumentHighlight("W [[1, 4] .. [1, 7]] | R [[3, 2] .. [3, 5]]");
});
}
@Test
public void multipleLinesMultipleOccurrences_WithWhitespaces() {
testDocumentHighlight((DocumentHighlightConfiguration cfg) -> {
String model =
"type A {\n" +
" op foo() { }\n" +
" op bar() {\n" +
" foo(10)\n" +
" }\n" +
"}";
cfg.setModel(model);
cfg.setLine(1);
cfg.setColumn(" op fo".length());
cfg.setExpectedDocumentHighlight("W [[1, 7] .. [1, 10]] | R [[3, 8] .. [3, 11]]");
});
}
}

View file

@ -1,146 +0,0 @@
/*******************************************************************************
* Copyright (c) 2016 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.ide.tests.server
import org.eclipse.lsp4j.DocumentHighlight
import org.eclipse.lsp4j.DocumentHighlightKind
import org.eclipse.lsp4j.Position
import org.eclipse.xtext.ide.server.occurrences.IDocumentHighlightService
import org.junit.Test
/**
* Class for testing the {@link DocumentHighlightService document highlight
* service} behavior through the language server.
*
* <p>
* The string representation of on single {@link DocumentHighlight highlight}
* instance is represented with the below pattern:
*
* <pre>
* R|W|T [{d}+, {d}+] .. [{d}+, {d}+]
* </pre>
*
* where the first character describes the {@link DocumentHighlightKind kind} of
* the document highlight. If missing, then the value is {@code NaN}. The values
* between the first square brackets are the start {@link Position#getLine()
* line} and the (zero-based) {@link Position#getCharacter() character offset}
* in the line. The second square brackets contains the end position of the
* selection and described with the same semantics as the first start range.
* Multiple highlight instances are separated by the {@code |} ("pipe")
* character.
*
* @author akos.kitta - Initial contribution and API
*
* @see DocumentHighlight
* @see IDocumentHighlightService
*/
class DocumentHighlightTest extends AbstractTestLangLanguageServerTest {
@Test
def void singleLineNoOccurrences_SelectionBeforeWriteSiteMethodName() {
testDocumentHighlight[
model = '''type A { op foo() { } }''';
column = '''type A { op'''.length;
expectedDocumentHighlight = '';
];
}
@Test
def void singleLineNoOccurrences_SelectionAfterWriteSiteMethodName() {
testDocumentHighlight[
model = '''type A { op foo() { } }''';
column = '''type A { op foo('''.length;
expectedDocumentHighlight = '';
];
}
@Test
def void singleLineSingleOccurrence() {
testDocumentHighlight[
model = '''type A { op foo() { } }''';
column = '''type A { op fo'''.length;
expectedDocumentHighlight = 'W [[0, 12] .. [0, 15]]';
];
}
@Test
def void singleLineSingleOccurrenceWithVariable() {
testDocumentHighlight[
model = '''type A { int foo op foo() { } }''';
column = '''type A { int fo'''.length;
expectedDocumentHighlight = 'W [[0, 13] .. [0, 16]]';
];
}
@Test
def void singleLineSingleOccurrenceWithMultipleTypes() {
testDocumentHighlight[
model = '''type A { op foo() { } } type B { op foo() { } }''';
column = '''type A { op fo'''.length;
expectedDocumentHighlight = 'W [[0, 12] .. [0, 15]]';
];
}
@Test
def void singleLineMultipleOccurrences_SelectionOnReadSite() {
testDocumentHighlight[
model = '''type A { op foo() { } op bar() { foo(10) } }''';
line = 0;
column = '''type A { op foo() { } op bar() { fo'''.length;
expectedDocumentHighlight = 'W [[0, 12] .. [0, 15]] | R [[0, 33] .. [0, 36]]';
];
}
@Test
def void singleLineMultipleOccurrences_SelectionOnWriteSite() {
testDocumentHighlight[
model = '''type A { op foo() { } op bar() { foo(10) } }''';
line = 0;
column = '''type A { op fo'''.length;
expectedDocumentHighlight = 'W [[0, 12] .. [0, 15]] | R [[0, 33] .. [0, 36]]';
];
}
@Test
def void multipleLinesMultipleOccurrences_WithHorizontalTabs() {
testDocumentHighlight[
// This snippet contains horizontal tabs for code indentation
model = '''
type A {
op foo() { }
op bar() {
foo(10)
}
}''';
line = 1;
// Same as above, horizontal tabs for code indentation
column = ''' op fo'''.length;
expectedDocumentHighlight = 'W [[1, 4] .. [1, 7]] | R [[3, 2] .. [3, 5]]';
];
}
@Test
def void multipleLinesMultipleOccurrences_WithWhitespaces() {
testDocumentHighlight[
// This snippet contains spaces for code indentation
model = '''
type A {
op foo() { }
op bar() {
foo(10)
}
}''';
line = 1;
// Same as above, spaces for code indentation
column = ''' op fo'''.length;
expectedDocumentHighlight = 'W [[1, 7] .. [1, 10]] | R [[3, 8] .. [3, 11]]';
];
}
}

View file

@ -0,0 +1,43 @@
/**
* Copyright (c) 2019, 2020 Sigasi N.V. (http://www.sigasi.com) 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.ide.tests.server;
import org.eclipse.xtext.testing.AbstractLanguageServerTest;
import org.eclipse.xtext.testing.DocumentHighlightConfiguration;
import org.junit.Test;
/**
* Class for testing the highlighting of reference that refer to the object in
* which they are embedded.
*/
public class DocumentHighlightTest2 extends AbstractLanguageServerTest {
public DocumentHighlightTest2() {
super("nestedRefs");
}
@Test
public void testHighlightDeclarationWithNestedReference() {
testDocumentHighlight((DocumentHighlightConfiguration cfg) -> {
cfg.setModel("decl myDecl end myDecl;");
cfg.setLine(0);
cfg.setColumn("decl myDec".length());
cfg.setExpectedDocumentHighlight("W [[0, 5] .. [0, 11]] | R [[0, 16] .. [0, 22]]");
});
}
@Test
public void testHighlightNestedReferenceInsideDeclaration() {
testDocumentHighlight((DocumentHighlightConfiguration cfg) -> {
cfg.setModel("decl myDecl end myDecl;");
cfg.setLine(0);
cfg.setColumn("decl myDecl end myDe".length());
cfg.setExpectedDocumentHighlight("W [[0, 5] .. [0, 11]] | R [[0, 16] .. [0, 22]]");
});
}
}

View file

@ -1,48 +0,0 @@
/*******************************************************************************
* Copyright (c) 2019 Sigasi N.V. (http://www.sigasi.com) 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.ide.tests.server
import org.eclipse.xtext.testing.AbstractLanguageServerTest
import org.junit.Test
/**
* Class for testing the highlighting of reference that refer to the object in which they are embedded.
*/
class DocumentHighlightTest2 extends AbstractLanguageServerTest {
new() {
super('nestedRefs');
}
@Test
def void testHighlightDeclarationWithNestedReference() {
testDocumentHighlight[
model = '''
decl myDecl end myDecl;
''';
line = 0
column = '''decl myDec'''.length;
expectedDocumentHighlight = 'W [[0, 5] .. [0, 11]] | R [[0, 16] .. [0, 22]]';
];
}
@Test
def void testHighlightNestedReferenceInsideDeclaration() {
testDocumentHighlight[
model = '''
decl myDecl end myDecl;
''';
line = 0
column = '''decl myDecl end myDe'''.length;
expectedDocumentHighlight = 'W [[0, 5] .. [0, 11]] | R [[0, 16] .. [0, 22]]';
];
}
}

View file

@ -0,0 +1,119 @@
/**
* Copyright (c) 2019, 2020 NumberFour AG (http://www.enfore.com) 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.ide.tests.server;
import java.io.File;
import java.util.Set;
import org.eclipse.lsp4j.DidChangeWatchedFilesParams;
import org.eclipse.lsp4j.FileChangeType;
import org.eclipse.lsp4j.FileEvent;
import org.eclipse.lsp4j.WorkspaceFolder;
import org.eclipse.xtext.ide.server.IMultiRootWorkspaceConfigFactory;
import org.eclipse.xtext.ide.server.MultiRootWorkspaceConfigFactory;
import org.eclipse.xtext.ide.server.ServerModule;
import org.eclipse.xtext.testing.ReferenceTestConfiguration;
import org.eclipse.xtext.util.Modules2;
import org.eclipse.xtext.workspace.FileProjectConfig;
import org.eclipse.xtext.workspace.WorkspaceConfig;
import org.junit.Assert;
import org.junit.Test;
import com.google.common.base.Joiner;
import com.google.common.collect.Lists;
import com.google.inject.Binder;
import com.google.inject.Module;
/**
* Checks functionality of method IProjectConfig#isIndexOnly()
*
* @author Marcus Mews - Initial contribution and API
*/
public class IndexOnlyProjectTest extends AbstractTestLangLanguageServerTest {
@Override
public com.google.inject.Module getServerModule() {
return Modules2.mixin(new ServerModule(), new Module() {
@Override
public void configure(Binder binder) {
binder.bind(IMultiRootWorkspaceConfigFactory.class).toInstance(new MultiRootWorkspaceConfigFactory() {
@Override
public void addProjectsForWorkspaceFolder(WorkspaceConfig workspaceConfig,
WorkspaceFolder workspaceFolder, Set<String> existingNames) {
String uri = null;
if (workspaceFolder != null) {
uri = workspaceFolder.getUri();
}
if (uri != null) {
FileProjectConfig project = new FileProjectConfig(
getUriExtensions().toUri(workspaceFolder.getUri()),
getUniqueProjectName(workspaceFolder.getName(), existingNames)) {
@Override
public boolean isIndexOnly() {
return true;
}
};
project.addSourceFolder(".");
workspaceConfig.addProject(project);
}
}
});
}
});
}
/**
* Shows that the resource is indexed
*/
@Test
public void testIndexByUsingReferences() {
testReferences((ReferenceTestConfiguration cfg) -> {
String model = "type Foo {}\n" + "type Bar {\n" + " Foo foo\n" + "}\n";
cfg.setModel(model);
cfg.setColumn("type F".length());
cfg.setExpectedReferences("MyModel.testlang [[2, 1] .. [2, 4]]\n");
});
}
/**
* Shows that the resource is not validated during initial build
*/
@Test
public void testInitializeBuildNoValidation() {
writeFile("MyType1.testlang", "type Test { NonExisting foo }");
initialize();
Assert.assertTrue(Joiner.on(",").join(getDiagnostics().entrySet()), getDiagnostics().isEmpty());
}
/**
* Shows that the error-free resource is not generated during initial build
*/
@Test
public void testInitializeBuildNoGeneration() {
writeFile("MyType1.testlang", "type TestType { int foo }");
initialize();
File outputFile = new File(root, "src-gen/TestType.java");
Assert.assertFalse(Joiner.on(",").join(getDiagnostics().entrySet()), outputFile.isFile());
}
/**
* Shows that the resource is not validated during incremental build
*/
@Test
public void testIncrementalBuildNoValidation() {
writeFile("MyType1.testlang", "type Test { NonExisting foo }");
initialize();
Assert.assertTrue(Joiner.on(",").join(getDiagnostics().entrySet()), getDiagnostics().isEmpty());
String path = writeFile("MyType2.testlang", "type NonExisting {}");
languageServer.getWorkspaceService().didChangeWatchedFiles(
new DidChangeWatchedFilesParams(Lists.newArrayList(new FileEvent(path, FileChangeType.Created))));
Assert.assertTrue(Joiner.on(",").join(getDiagnostics().entrySet()), getDiagnostics().isEmpty());
}
}

View file

@ -1,118 +0,0 @@
/*******************************************************************************
* Copyright (c) 2019 NumberFour AG (http://www.enfore.com) 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.ide.tests.server
import com.google.inject.Module
import java.io.File
import java.util.Set
import org.eclipse.lsp4j.DidChangeWatchedFilesParams
import org.eclipse.lsp4j.FileChangeType
import org.eclipse.lsp4j.FileEvent
import org.eclipse.lsp4j.WorkspaceFolder
import org.eclipse.xtext.ide.server.IMultiRootWorkspaceConfigFactory
import org.eclipse.xtext.ide.server.MultiRootWorkspaceConfigFactory
import org.eclipse.xtext.ide.server.ServerModule
import org.eclipse.xtext.util.Modules2
import org.eclipse.xtext.workspace.FileProjectConfig
import org.eclipse.xtext.workspace.WorkspaceConfig
import org.junit.Test
import static org.junit.Assert.*
/**
* Checks functionality of method IProjectConfig#isIndexOnly()
*
* @author Marcus Mews - Initial contribution and API
*/
class IndexOnlyProjectTest extends AbstractTestLangLanguageServerTest {
override Module getServerModule() {
Modules2.mixin(new ServerModule, [
bind(IMultiRootWorkspaceConfigFactory).toInstance(new MultiRootWorkspaceConfigFactory() {
override addProjectsForWorkspaceFolder(WorkspaceConfig workspaceConfig, WorkspaceFolder workspaceFolder, Set<String> existingNames) {
if (workspaceFolder?.uri !== null) {
val project = new FileProjectConfig(uriExtensions.toUri(workspaceFolder.uri), getUniqueProjectName(workspaceFolder.name, existingNames)) {
override boolean isIndexOnly() {
return true;
}
};
project.addSourceFolder(".");
workspaceConfig.addProject(project);
}
}
})
])
}
/** Shows that the resource is indexed */
@Test
def void testIndexByUsingReferences() {
testReferences[
model = '''
type Foo {}
type Bar {
Foo foo
}
'''
column = 'type F'.length
expectedReferences = '''
MyModel.testlang [[2, 1] .. [2, 4]]
'''
]
}
/** Shows that the resource is not validated during initial build */
@Test
def void testInitializeBuildNoValidation() {
'MyType1.testlang'.writeFile( '''
type Test {
NonExisting foo
}
''')
initialize
assertTrue(diagnostics.entrySet.join(','), diagnostics.empty)
}
/** Shows that the error-free resource is not generated during initial build */
@Test
def void testInitializeBuildNoGeneration() {
'MyType1.testlang'.writeFile( '''
type TestType {
int foo
}
''')
initialize
val outputFile = new File(root, "src-gen/TestType.java");
assertFalse(diagnostics.entrySet.join(','), outputFile.isFile)
}
/** Shows that the resource is not validated during incremental build */
@Test
def void testIncrementalBuildNoValidation() {
'MyType1.testlang'.writeFile( '''
type Test {
NonExisting foo
}
''')
initialize
assertTrue(diagnostics.entrySet.join(','), diagnostics.empty)
val path = 'MyType2.testlang'.writeFile('''
type NonExisting {
}
''')
languageServer.getWorkspaceService.didChangeWatchedFiles(
new DidChangeWatchedFilesParams(#[new FileEvent(path, FileChangeType.Created)])
)
assertTrue(diagnostics.entrySet.join(','), diagnostics.empty)
}
}

View file

@ -0,0 +1,69 @@
/**
* Copyright (c) 2016, 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.ide.tests.server;
import java.util.List;
import org.eclipse.lsp4j.DidOpenTextDocumentParams;
import org.eclipse.lsp4j.TextDocumentItem;
import org.eclipse.lsp4j.jsonrpc.services.ServiceEndpoints;
import org.eclipse.xtext.ide.tests.testlanguage.ide.TestLangLSPExtension;
import org.eclipse.xtext.ide.tests.testlanguage.ide.TestLangLSPExtension.TextOfLineParam;
import org.eclipse.xtext.ide.tests.testlanguage.ide.TestLangLSPExtension.TextOfLineResult;
import org.eclipse.xtext.xbase.lib.IterableExtensions;
import org.junit.Assert;
import org.junit.Test;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
/**
* @author efftinge - Initial contribution and API
*/
public class LspExtensionTest extends AbstractTestLangLanguageServerTest {
@Test
public void testExtension() throws Exception {
String fileURI = writeFile("mydoc.testlang", "");
initialize();
TestLangLSPExtension ext = ServiceEndpoints.toServiceObject(languageServer, TestLangLSPExtension.class);
DidOpenTextDocumentParams didOpenTextDocumentParams = new DidOpenTextDocumentParams();
String text =
"foo bar" + System.lineSeparator() +
"baz test" + System.lineSeparator() +
" bla blubb";
didOpenTextDocumentParams.setTextDocument(new TextDocumentItem(fileURI, "testlang", 0, text));
languageServer.didOpen(didOpenTextDocumentParams);
TextOfLineParam textOfLineParam = new TextOfLineParam();
textOfLineParam.uri = fileURI;
textOfLineParam.line = 1;
TextOfLineResult result = ext.getTextOfLine(textOfLineParam).get();
Assert.assertEquals("baz test", result.text);
Assert.assertEquals(2,
IterableExtensions.size(Iterables.filter(Iterables.transform(notifications, n -> n.getValue()),
TestLangLSPExtension.BuildNotification.class)));
}
@Test
public void testExtension_readIndex() throws Exception {
writeFile("model.testlang",
"type C {\n" +
" op baz() { }\n" +
"}\n" +
"type A {\n" +
" op foo() { }\n" +
"}\n" +
"type B {\n" +
" op bar() { }\n" +
"}\n");
initialize();
TestLangLSPExtension ext = ServiceEndpoints.toServiceObject(languageServer, TestLangLSPExtension.class);
List<String> actual = IterableExtensions.sort(Lists.newArrayList(ext.getAllOpNames().get()));
Assert.assertEquals(Lists.newArrayList("bar", "baz", "foo"), actual);
}
}

View file

@ -1,65 +0,0 @@
/*******************************************************************************
* Copyright (c) 2016 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.ide.tests.server
import org.eclipse.lsp4j.DidOpenTextDocumentParams
import org.eclipse.lsp4j.TextDocumentItem
import org.eclipse.lsp4j.jsonrpc.services.ServiceEndpoints
import org.eclipse.xtext.ide.tests.testlanguage.ide.TestLangLSPExtension
import org.eclipse.xtext.ide.tests.testlanguage.ide.TestLangLSPExtension.TextOfLineParam
import org.junit.Assert
import org.junit.Test
import org.eclipse.xtext.ide.tests.testlanguage.ide.TestLangLSPExtension.BuildNotification
/**
* @author efftinge - Initial contribution and API
*/
class LspExtensionTest extends AbstractTestLangLanguageServerTest {
@Test def void testExtension() {
val fileURI = "mydoc.testlang".writeFile("")
initialize
val ext = ServiceEndpoints.toServiceObject(languageServer, TestLangLSPExtension)
languageServer.didOpen(new DidOpenTextDocumentParams => [
it.textDocument = new TextDocumentItem => [
uri = fileURI
text = '''
foo bar
baz test
bla blubb
'''
]
])
val result = ext.getTextOfLine(new TextOfLineParam => [
uri = fileURI
line = 1
]).get
Assert.assertEquals("baz test", result.text)
Assert.assertEquals(2, notifications.map[value].filter(BuildNotification).size)
}
@Test def void testExtension_readIndex() {
'model.testlang'.writeFile('''
type C {
op baz() { }
}
type A {
op foo() { }
}
type B {
op bar() { }
}
''')
initialize
val ext = ServiceEndpoints.toServiceObject(languageServer, TestLangLSPExtension)
val actual = ext.allOpNames.get.toList.sort
Assert.assertEquals(#['bar', 'baz', 'foo'], actual)
}
}

View file

@ -0,0 +1,107 @@
/**
* Copyright (c) 2016, 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.ide.tests.server;
import java.io.File;
import java.io.FileWriter;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.eclipse.emf.common.util.URI;
import org.eclipse.xtext.diagnostics.Diagnostic;
import org.eclipse.xtext.ide.server.IMultiRootWorkspaceConfigFactory;
import org.eclipse.xtext.ide.server.MultiProjectWorkspaceConfigFactory;
import org.eclipse.xtext.ide.server.ServerModule;
import org.eclipse.xtext.ide.server.WorkspaceManager;
import org.eclipse.xtext.util.CancelIndicator;
import org.eclipse.xtext.util.Files;
import org.eclipse.xtext.util.Modules2;
import org.eclipse.xtext.validation.Issue;
import org.eclipse.xtext.xbase.lib.IterableExtensions;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import com.google.inject.AbstractModule;
import com.google.inject.Guice;
import com.google.inject.Inject;
import com.google.inject.Injector;
/**
* @author Jan Koehnlein - Initial contribution and API
*/
public class MultiProjectTest {
private File project0;
private File project1;
private Map<URI, List<Issue>> diagnostics = new HashMap<>();
@Inject
private WorkspaceManager workspaceManager;
@Test
public void testCrossProjectLink() throws Exception {
URI foo = createFile(project0, "Foo.testlang", "type Foo { Bar bar }");
URI bar = createFile(project1, "Bar.testlang", "type Bar {}");
workspaceManager.doBuild(Lists.newArrayList(foo, bar), Collections.emptyList(), CancelIndicator.NullImpl);
Assert.assertEquals(2, diagnostics.size());
Assert.assertEquals(1, diagnostics.get(foo).size());
Assert.assertEquals(Diagnostic.LINKING_DIAGNOSTIC, Iterables.getFirst(diagnostics.get(foo), null).getCode());
Assert.assertTrue(diagnostics.get(bar).isEmpty());
diagnostics.clear();
workspaceManager.getProjectManager(project0.getName()).getProjectDescription().getDependencies()
.add(project1.getName());
workspaceManager.doBuild(Lists.newArrayList(foo, bar), Collections.emptyList(), CancelIndicator.NullImpl);
Assert.assertEquals(2, diagnostics.size());
Assert.assertTrue(diagnostics.get(foo).isEmpty());
Assert.assertTrue(diagnostics.get(bar).isEmpty());
}
@Before
public void setup() throws Exception {
Injector injector = Guice.createInjector(Modules2.mixin(new ServerModule(), new AbstractModule() {
@Override
protected void configure() {
bind(IMultiRootWorkspaceConfigFactory.class).to(MultiProjectWorkspaceConfigFactory.class);
}
}));
injector.injectMembers(this);
File workspaceRoot = getRoot("test-data");
project0 = new File(workspaceRoot, "test-project0");
project1 = new File(workspaceRoot, "test-project1");
project0.mkdir();
project1.mkdir();
workspaceManager.initialize(URI.createFileURI(workspaceRoot.getAbsolutePath()),
(URI $0, Iterable<Issue> $1) -> diagnostics.put($0, IterableExtensions.toList($1)), null);
}
protected File getRoot(String path) throws Exception {
File root = new File(path);
if (!root.mkdirs()) {
Files.cleanFolder(root, null, true, false);
}
root.deleteOnExit();
return root;
}
public URI createFile(File root, String path, CharSequence contents) throws Exception {
File file = new File(root, path);
file.getParentFile().mkdirs();
file.createNewFile();
try (FileWriter fileWriter = new FileWriter(file)) {
fileWriter.write(contents.toString());
}
return URI.createFileURI(file.getAbsolutePath());
}
}

View file

@ -1,106 +0,0 @@
/*******************************************************************************
* Copyright (c) 2016, 2017 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.ide.tests.server
import com.google.inject.AbstractModule
import com.google.inject.Guice
import com.google.inject.Inject
import java.io.File
import java.io.FileWriter
import java.util.List
import java.util.Map
import org.eclipse.emf.common.util.URI
import org.eclipse.xtext.diagnostics.Diagnostic
import org.eclipse.xtext.ide.server.IMultiRootWorkspaceConfigFactory
import org.eclipse.xtext.ide.server.MultiProjectWorkspaceConfigFactory
import org.eclipse.xtext.ide.server.ServerModule
import org.eclipse.xtext.ide.server.WorkspaceManager
import org.eclipse.xtext.util.CancelIndicator
import org.eclipse.xtext.util.Files
import org.eclipse.xtext.util.Modules2
import org.eclipse.xtext.validation.Issue
import org.junit.Before
import org.junit.Test
import static org.junit.Assert.*
/**
* @author Jan Koehnlein - Initial contribution and API
*/
class MultiProjectTest {
File project0
File project1
Map<URI, List<Issue>> diagnostics = newHashMap
@Inject WorkspaceManager workspaceManager
@Test
def void testCrossProjectLink() {
val foo = createFile(project0, 'Foo.testlang', '''
type Foo {
Bar bar
}
''')
val bar = createFile(project1, 'Bar.testlang', '''
type Bar {
}
''')
workspaceManager.doBuild(#[foo, bar], emptyList, CancelIndicator.NullImpl)
assertEquals(2, diagnostics.size)
assertEquals(1, diagnostics.get(foo).size)
assertEquals(Diagnostic.LINKING_DIAGNOSTIC, diagnostics.get(foo).head.code)
assertTrue(diagnostics.get(bar).empty)
// add a dependency from project0 to project1
diagnostics.clear
workspaceManager.getProjectManager(project0.name).projectDescription.dependencies += project1.name
workspaceManager.doBuild(#[foo, bar], emptyList, CancelIndicator.NullImpl)
assertEquals(2, diagnostics.size)
assertTrue(diagnostics.get(foo).empty)
assertTrue(diagnostics.get(bar).empty)
}
@Before
def void setup() {
val injector = Guice.createInjector(Modules2.mixin(new ServerModule, new AbstractModule() {
override protected configure() {
bind(IMultiRootWorkspaceConfigFactory).to(MultiProjectWorkspaceConfigFactory)
}
}))
injector.injectMembers(this)
val workspaceRoot = getRoot("test-data")
project0 = new File(workspaceRoot, "test-project0")
project1 = new File(workspaceRoot, "test-project1")
project0.mkdir
project1.mkdir
workspaceManager.initialize(URI.createFileURI(workspaceRoot.absolutePath), [diagnostics.put($0, $1.toList)], null)
}
protected def getRoot(String path) {
val root = new File(path)
if (!root.mkdirs) {
Files.cleanFolder(root, null, true, false)
}
root.deleteOnExit
root
}
def URI createFile(File root, String path, CharSequence contents) {
val file = new File(root, path)
file.parentFile.mkdirs
file.createNewFile
new FileWriter(file) => [
write(contents.toString)
close
]
return URI.createFileURI(file.absolutePath)
}
}

View file

@ -0,0 +1,115 @@
/**
* Copyright (c) 2016, 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.ide.tests.server;
import org.eclipse.lsp4j.DidChangeTextDocumentParams;
import org.eclipse.lsp4j.DidChangeWatchedFilesParams;
import org.eclipse.lsp4j.FileChangeType;
import org.eclipse.lsp4j.FileEvent;
import org.eclipse.lsp4j.Position;
import org.eclipse.lsp4j.Range;
import org.eclipse.lsp4j.TextDocumentContentChangeEvent;
import org.eclipse.lsp4j.VersionedTextDocumentIdentifier;
import org.junit.Assert;
import org.junit.Test;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
/**
* @author Sven Efftinge - Initial contribution and API
*/
public class OpenDocumentTest extends AbstractTestLangLanguageServerTest {
@Test
public void testOpenedDocumentShadowsPersistedFile() {
String model =
"type Test {\n" +
" NonExisting foo\n" +
"}";
String firstFile = writeFile("MyType1.testlang", model);
initialize();
assertEquals("Couldn't resolve reference to TypeDeclaration 'NonExisting'.",
Iterables.getFirst(getDiagnostics().get(firstFile), null).getMessage());
String path = writeFile("MyType2.testlang", "\n type Foo {\n }\n ");
languageServer.getWorkspaceService().didChangeWatchedFiles(new DidChangeWatchedFilesParams(
Lists.newArrayList(new FileEvent(path, FileChangeType.Created))));
assertEquals("Couldn't resolve reference to TypeDeclaration 'NonExisting'.",
Iterables.getFirst(getDiagnostics().get(firstFile), null).getMessage());
String model2 = "type NonExisting {}";
open(path, model2);
Assert.assertNull(Iterables.getFirst(getDiagnostics().get(firstFile), null));
close(path);
assertEquals("Couldn't resolve reference to TypeDeclaration 'NonExisting'.",
Iterables.getFirst(getDiagnostics().get(firstFile), null).getMessage());
}
@Test
public void testDidChange() {
String model =
"type Test {\n" +
" NonExisting foo\n" +
"}\n";
String firstFile = writeFile("MyType1.testlang",
model);
initialize();
assertEquals("Couldn't resolve reference to TypeDeclaration 'NonExisting'.",
Iterables.getFirst(getDiagnostics().get(firstFile), null).getMessage());
open(firstFile, model);
assertEquals("Couldn't resolve reference to TypeDeclaration 'NonExisting'.",
Iterables.getFirst(getDiagnostics().get(firstFile), null).getMessage());
DidChangeTextDocumentParams didChangeTextDocumentParams = new DidChangeTextDocumentParams();
didChangeTextDocumentParams.setTextDocument(new VersionedTextDocumentIdentifier(firstFile, 2));
TextDocumentContentChangeEvent textDocumentContentChangeEvent = new TextDocumentContentChangeEvent("Test");
textDocumentContentChangeEvent.setRange(new Range(new Position(1, 4), new Position(1, 15)));
didChangeTextDocumentParams.setContentChanges(Lists.newArrayList(textDocumentContentChangeEvent));
languageServer.didChange(didChangeTextDocumentParams);
Assert.assertNull(Iterables.getFirst(getDiagnostics().get(firstFile), null));
}
@Test
public void testDidClose() {
String fileURI = writeFile("Foo.testlang", "");
initialize();
String referencingFileURI = getVirtualFile("Bar.testlang");
String model =
"type Bar {\n" +
" Foo foo\n" +
"}\n";
open(referencingFileURI, model);
Assert.assertFalse(getDiagnostics().get(referencingFileURI).isEmpty());
open(fileURI, "type Foo {}");
Assert.assertTrue(getDiagnostics().get(referencingFileURI).isEmpty());
close(fileURI);
Assert.assertFalse(getDiagnostics().get(referencingFileURI).isEmpty());
}
@Test
public void testDidCloseInMemory() {
initialize();
String fileURI = getVirtualFile("Foo.testlang");
open(fileURI, "type Foo {}");
String referencingFileURI = getVirtualFile("Bar.testlang");
String model =
"type Bar {\n" +
" Foo foo\n" +
"}\n";
open(referencingFileURI, model);
Assert.assertTrue(getDiagnostics().get(referencingFileURI).isEmpty());
close(fileURI);
Assert.assertFalse(getDiagnostics().get(referencingFileURI).isEmpty());
}
@Test
public void testInMemory_GH_456() {
initialize();
String uri = "inmemory:/foo/bar.testlang";
open(uri, "type Foo { }");
Assert.assertNotNull("Diagnostics could be empty but never null.", getDiagnostics().get(uri));
}
}

View file

@ -1,147 +0,0 @@
/*******************************************************************************
* Copyright (c) 2016, 2017 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.ide.tests.server
import org.eclipse.lsp4j.DidChangeTextDocumentParams
import org.eclipse.lsp4j.DidChangeWatchedFilesParams
import org.eclipse.lsp4j.FileChangeType
import org.eclipse.lsp4j.FileEvent
import org.eclipse.lsp4j.Position
import org.eclipse.lsp4j.Range
import org.eclipse.lsp4j.TextDocumentContentChangeEvent
import org.eclipse.lsp4j.VersionedTextDocumentIdentifier
import org.junit.Test
import static org.junit.Assert.*
/**
* @author Sven Efftinge - Initial contribution and API
*/
class OpenDocumentTest extends AbstractTestLangLanguageServerTest {
@Test
def void testOpenedDocumentShadowsPersistedFile() {
val firstFile = 'MyType1.testlang'.writeFile( '''
type Test {
NonExisting foo
}
''')
initialize
assertEquals("Couldn't resolve reference to TypeDeclaration 'NonExisting'.", diagnostics.get(firstFile).head.message)
val path = 'MyType2.testlang'.writeFile( '''
type Foo {
}
''')
languageServer.getWorkspaceService.didChangeWatchedFiles(
new DidChangeWatchedFilesParams(#[
new FileEvent(path, FileChangeType.Created)
])
)
// still erroneous
assertEquals("Couldn't resolve reference to TypeDeclaration 'NonExisting'.", diagnostics.get(firstFile).head.message)
// let's open the document with a different content
open(path, '''
type NonExisting {
}
''')
assertNull(diagnostics.get(firstFile).head)
// let's close again
close(path)
assertEquals("Couldn't resolve reference to TypeDeclaration 'NonExisting'.", diagnostics.get(firstFile).head.message)
}
@Test
def void testDidChange() {
val firstFile = 'MyType1.testlang'.writeFile( '''
type Test {
NonExisting foo
}
''')
initialize
assertEquals("Couldn't resolve reference to TypeDeclaration 'NonExisting'.", diagnostics.get(firstFile).head.message)
open(firstFile, '''
type Test {
NonExisting foo
}
''')
assertEquals("Couldn't resolve reference to TypeDeclaration 'NonExisting'.", diagnostics.get(firstFile).head.message)
languageServer.didChange(new DidChangeTextDocumentParams => [
textDocument = new VersionedTextDocumentIdentifier => [
uri = firstFile
version = 2
]
contentChanges = #[
new TextDocumentContentChangeEvent => [
range = new Range(new Position(1, 4), new Position(1, 15))
text = "Test"
]
]
])
assertNull(diagnostics.get(firstFile).head)
}
@Test
def void testDidClose() {
val fileURI = 'Foo.testlang'.writeFile('')
initialize
val referencingFileURI = 'Bar.testlang'.virtualFile
referencingFileURI.open('''
type Bar {
Foo foo
}
''')
assertFalse(diagnostics.get(referencingFileURI).empty)
fileURI.open('type Foo {}')
assertTrue(diagnostics.get(referencingFileURI).empty)
close(fileURI);
assertFalse(diagnostics.get(referencingFileURI).empty)
}
@Test
def void testDidCloseInMemory() {
initialize
val fileURI = 'Foo.testlang'.virtualFile
fileURI.open('type Foo {}')
val referencingFileURI = 'Bar.testlang'.virtualFile
referencingFileURI.open('''
type Bar {
Foo foo
}
''')
assertTrue(diagnostics.get(referencingFileURI).empty)
close(fileURI);
assertFalse(diagnostics.get(referencingFileURI).empty)
}
@Test
def void testInMemory_GH_456() {
initialize
val uri = 'inmemory:/foo/bar.testlang';
open(uri, '''
type Foo { }
''');
assertNotNull('''Diagnostics could be empty but never null.''', diagnostics.get(uri));
}
}

View file

@ -0,0 +1,68 @@
/**
* Copyright (c) 2016, 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.ide.tests.server;
import org.eclipse.xtext.testing.ReferenceTestConfiguration;
import org.junit.Test;
import com.google.common.collect.ImmutableMap;
/**
* @author kosyakov - Initial contribution and API
*/
public class ReferenceTest extends AbstractTestLangLanguageServerTest {
@Test
public void testReferences_01() {
testReferences((ReferenceTestConfiguration it) -> {
String model =
"type Foo {}\n" +
"type Bar {\n" +
" Foo foo\n" +
"}";
it.setModel(model);
it.setColumn("type F".length());
it.setExpectedReferences("MyModel.testlang [[2, 1] .. [2, 4]]\n");
});
}
@Test
public void testReferences_02() {
testReferences((ReferenceTestConfiguration it) -> {
String model =
"type Foo {}\n" +
"type Bar {\n" +
" Foo foo\n" +
"}";
it.setModel(model);
it.setColumn("type F".length());
it.setIncludeDeclaration(true);
it.setExpectedReferences(
"MyModel.testlang [[0, 5] .. [0, 8]]\n" +
"MyModel.testlang [[2, 1] .. [2, 4]]\n");
});
}
@Test
public void testReferences_03_acrossFiles() {
testReferences((ReferenceTestConfiguration it) -> {
it.setFilesInScope(ImmutableMap.<String, CharSequence>builder().put("foo.testlang", "type Foo {}").build());
String model =
"type Bar {\n" +
" Foo foo" +
"}\n";
it.setModel(model);
it.setLine(1);
it.setColumn(6);
it.setIncludeDeclaration(true);
it.setExpectedReferences(
"foo.testlang [[0, 5] .. [0, 8]]\n" +
"MyModel.testlang [[1, 4] .. [1, 7]]\n");
});
}
}

View file

@ -1,75 +0,0 @@
/*******************************************************************************
* Copyright (c) 2016 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.ide.tests.server
import org.junit.Test
/**
* @author kosyakov - Initial contribution and API
*/
class ReferenceTest extends AbstractTestLangLanguageServerTest {
@Test
def void testReferences_01() {
testReferences[
model = '''
type Foo {}
type Bar {
Foo foo
}
'''
column = 'type F'.length
expectedReferences = '''
MyModel.testlang [[2, 1] .. [2, 4]]
'''
]
}
@Test
def void testReferences_02() {
testReferences[
model = '''
type Foo {}
type Bar {
Foo foo
}
'''
column = 'type F'.length
includeDeclaration = true
expectedReferences = '''
MyModel.testlang [[0, 5] .. [0, 8]]
MyModel.testlang [[2, 1] .. [2, 4]]
'''
]
}
@Test
def void testReferences_03_acrossFiles() {
testReferences[
filesInScope = #{
"foo.testlang" -> '''
type Foo {}
'''
}
model = '''
type Bar {
Foo foo
}
'''
line = 1
column = 6
includeDeclaration = true
expectedReferences = '''
foo.testlang [[0, 5] .. [0, 8]]
MyModel.testlang [[1, 4] .. [1, 7]]
'''
]
}
}

View file

@ -0,0 +1,147 @@
/**
* Copyright (c) 2016, 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.ide.tests.server;
import java.util.List;
import java.util.concurrent.ExecutionException;
import org.eclipse.lsp4j.DefinitionParams;
import org.eclipse.lsp4j.Diagnostic;
import org.eclipse.lsp4j.DidChangeWatchedFilesParams;
import org.eclipse.lsp4j.FileChangeType;
import org.eclipse.lsp4j.FileEvent;
import org.eclipse.lsp4j.TextDocumentIdentifier;
import org.eclipse.lsp4j.jsonrpc.ResponseErrorException;
import org.eclipse.lsp4j.jsonrpc.messages.ResponseErrorCode;
import org.junit.Assert;
import org.junit.Test;
import com.google.common.base.Joiner;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
/**
* @author Sven Efftinge - Initial contribution and API
*/
public class ServerTest extends AbstractTestLangLanguageServerTest {
@Test
public void testInitializeBuild() {
String model =
"type Test {\n" +
" string foo\n" +
"}\n";
writeFile("MyType1.testlang", model);
initialize();
Assert.assertTrue(Joiner.on(",").join(getDiagnostics().entrySet()),
Iterables.getFirst(getDiagnostics().values(), null).isEmpty());
}
@Test
public void testInitializeBuildWithError() {
String model =
"type Test {\n" +
" NonExisting foo\n" +
"}\n";
writeFile("MyType1.testlang", model);
initialize();
Diagnostic firstDiagnostic = getFirstDiagnostic();
assertEquals("Couldn't resolve reference to TypeDeclaration 'NonExisting'.", firstDiagnostic.getMessage());
Assert.assertEquals(1, firstDiagnostic.getRange().getStart().getLine());
Assert.assertEquals(4, firstDiagnostic.getRange().getStart().getCharacter());
Assert.assertEquals(1, firstDiagnostic.getRange().getEnd().getLine());
Assert.assertEquals(15, firstDiagnostic.getRange().getEnd().getCharacter());
}
private Diagnostic getFirstDiagnostic() {
return Iterables.getFirst(Iterables.getFirst(getDiagnostics().values(), null), null);
}
@Test
public void testPublishDiagnosticsAfterInitialized() {
String model =
"type Test {\n" +
" NonExisting foo\n" +
"}\n";
writeFile("MyType1.testlang", model);
initialize(null, false);
Assert.assertTrue("Diagnostics produced before 'initialized' was called", getDiagnostics().isEmpty());
}
@Test
public void testIncrementalBuildWithError() {
String model =
"type Test {\n" +
" NonExisting foo\n" +
"}\n";
writeFile("MyType1.testlang", model);
initialize();
assertEquals("Couldn't resolve reference to TypeDeclaration 'NonExisting'.", getFirstDiagnostic().getMessage());
String model2 =
"type NonExisting {\n" +
"}\n";
String path = writeFile("MyType2.testlang", model2);
languageServer.getWorkspaceService().didChangeWatchedFiles(
new DidChangeWatchedFilesParams(Lists.newArrayList(new FileEvent(path, FileChangeType.Created))));
Assert.assertNotNull(getDiagnostics().get(path));
for (List<Diagnostic> d : getDiagnostics().values()) {
Assert.assertTrue(Joiner.on(",").join(d), d.isEmpty());
}
}
@Test
public void testIncrementalDeletion() {
String model =
"type Test {\n" +
" NonExisting foo\n" +
"}\n";
String path = writeFile("MyType1.testlang", model);
initialize();
assertEquals("Couldn't resolve reference to TypeDeclaration 'NonExisting'.", getFirstDiagnostic().getMessage());
deleteFile("MyType1.testlang");
languageServer.getWorkspaceService().didChangeWatchedFiles(
new DidChangeWatchedFilesParams(Lists.newArrayList(new FileEvent(path, FileChangeType.Deleted))));
Assert.assertTrue(Iterables.getFirst(getDiagnostics().values(), null).isEmpty());
}
@Test
public void testTwoFilesDeleteClose() {
String fileURI = writeFile("Foo.testlang", "");
initialize();
String referencingFileURI = getVirtualFile("Bar.testlang");
String model =
"type Bar {\n" +
" Foo foo\n" +
"}\n";
open(referencingFileURI, model);
Assert.assertFalse("Bar.testlang references missing type Foo from Foo.testlang: expect error",
getDiagnostics().get(referencingFileURI).isEmpty());
open(fileURI, "type Foo {}");
Assert.assertTrue("Bar.testlang references type Foo from Foo.testlang: expect no error",
getDiagnostics().get(referencingFileURI).isEmpty());
deleteFile(fileURI);
languageServer.getWorkspaceService().didChangeWatchedFiles(
new DidChangeWatchedFilesParams(Lists.newArrayList(new FileEvent(fileURI, FileChangeType.Deleted))));
Assert.assertTrue("delete file on disk: expect no error", getDiagnostics().get(referencingFileURI).isEmpty());
close(fileURI);
Assert.assertFalse("close deleted file: expect error", getDiagnostics().get(referencingFileURI).isEmpty());
}
@Test
public void testMissingInitialize() throws Exception {
try {
DefinitionParams definitionParams = new DefinitionParams();
definitionParams.setTextDocument(new TextDocumentIdentifier("file:/home/test/workspace/mydoc.testlang"));
languageServer.definition(definitionParams).get();
Assert.fail("Expected a ResponseErrorException");
} catch (ExecutionException exception) {
Assert.assertEquals(ResponseErrorCode.serverNotInitialized.getValue(),
((ResponseErrorException) exception.getCause()).getResponseError().getCode());
}
}
}

View file

@ -1,147 +0,0 @@
/*******************************************************************************
* Copyright (c) 2016, 2017 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.ide.tests.server
import java.util.concurrent.ExecutionException
import org.eclipse.lsp4j.DidChangeWatchedFilesParams
import org.eclipse.lsp4j.FileChangeType
import org.eclipse.lsp4j.FileEvent
import org.eclipse.lsp4j.TextDocumentIdentifier
import org.eclipse.lsp4j.jsonrpc.ResponseErrorException
import org.eclipse.lsp4j.jsonrpc.messages.ResponseErrorCode
import org.junit.Assert
import org.junit.Test
import static org.junit.Assert.*
import org.eclipse.lsp4j.DefinitionParams
/**
* @author Sven Efftinge - Initial contribution and API
*/
class ServerTest extends AbstractTestLangLanguageServerTest {
@Test
def void testInitializeBuild() {
'MyType1.testlang'.writeFile('''
type Test {
string foo
}
''')
initialize
assertTrue(diagnostics.entrySet.join(','), diagnostics.values.head.empty)
}
@Test
def void testInitializeBuildWithError() {
'MyType1.testlang'.writeFile( '''
type Test {
NonExisting foo
}
''')
initialize
assertEquals("Couldn't resolve reference to TypeDeclaration 'NonExisting'.", diagnostics.values.head.head?.message)
assertEquals(1, diagnostics.values.head.head.range.start.line)
assertEquals(4, diagnostics.values.head.head.range.start.character)
assertEquals(1, diagnostics.values.head.head.range.end.line)
assertEquals(15, diagnostics.values.head.head.range.end.character)
}
@Test
def void testPublishDiagnosticsAfterInitialized() {
'MyType1.testlang'.writeFile( '''
type Test {
NonExisting foo
}
''')
initialize(null, false)
assertTrue("Diagnostics produced before 'initialized' was called", diagnostics.empty)
}
@Test
def void testIncrementalBuildWithError() {
'MyType1.testlang'.writeFile( '''
type Test {
NonExisting foo
}
''')
initialize
assertEquals("Couldn't resolve reference to TypeDeclaration 'NonExisting'.", diagnostics.values.head.head.message)
val path = 'MyType2.testlang'.writeFile('''
type NonExisting {
}
''')
languageServer.getWorkspaceService.didChangeWatchedFiles(
new DidChangeWatchedFilesParams(#[new FileEvent(path, FileChangeType.Created)])
)
assertNotNull(diagnostics.get(path))
assertTrue(diagnostics.values.join(','), diagnostics.values.forall[empty])
}
@Test
def void testIncrementalDeletion() {
val path = 'MyType1.testlang'.writeFile( '''
type Test {
NonExisting foo
}
''')
initialize
assertEquals("Couldn't resolve reference to TypeDeclaration 'NonExisting'.",
diagnostics.values.head.head.message)
'MyType1.testlang'.deleteFile
languageServer.getWorkspaceService.didChangeWatchedFiles(
new DidChangeWatchedFilesParams(#[new FileEvent(path, FileChangeType.Deleted)])
)
assertTrue(diagnostics.values.head.empty)
}
@Test
def void testTwoFilesDeleteClose() {
// create two files with cross ref
val fileURI = 'Foo.testlang'.writeFile('')
initialize
val referencingFileURI = 'Bar.testlang'.virtualFile
referencingFileURI.open('''
type Bar {
Foo foo
}
''')
assertFalse("Bar.testlang references missing type Foo from Foo.testlang: expect error",
diagnostics.get(referencingFileURI).empty)
fileURI.open('type Foo {}')
// no errors
assertTrue("Bar.testlang references type Foo from Foo.testlang: expect no error",
diagnostics.get(referencingFileURI).empty)
fileURI.deleteFile
languageServer.getWorkspaceService.didChangeWatchedFiles(
new DidChangeWatchedFilesParams(#[new FileEvent(fileURI, FileChangeType.Deleted)])
)
assertTrue("delete file on disk: expect no error", diagnostics.get(referencingFileURI).empty)
close(fileURI);
assertFalse("close deleted file: expect error", diagnostics.get(referencingFileURI).empty)
}
@Test
def void testMissingInitialize() {
try {
languageServer.definition(new DefinitionParams => [
textDocument = new TextDocumentIdentifier => [
uri = 'file:/home/test/workspace/mydoc.testlang'
]
]).get
Assert.fail("Expected a ResponseErrorException")
} catch (ExecutionException exception) {
Assert.assertEquals(ResponseErrorCode.serverNotInitialized.value, (exception.cause as ResponseErrorException).responseError.code)
}
}
}

View file

@ -0,0 +1,116 @@
/**
* Copyright (c) 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.ide.tests.server;
import java.io.File;
import java.io.FileWriter;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import org.eclipse.lsp4j.DidChangeWorkspaceFoldersParams;
import org.eclipse.lsp4j.InitializeParams;
import org.eclipse.lsp4j.WorkspaceFolder;
import org.eclipse.lsp4j.WorkspaceFoldersChangeEvent;
import org.eclipse.xtext.ide.server.ILanguageServerAccess;
import org.eclipse.xtext.ide.server.UriExtensions;
import org.eclipse.xtext.ide.server.WorkspaceManager;
import org.eclipse.xtext.resource.IResourceDescription;
import org.eclipse.xtext.util.Modules2;
import org.eclipse.xtext.xbase.lib.Procedures.Procedure0;
import org.junit.Assert;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import com.google.common.collect.Lists;
import com.google.inject.AbstractModule;
import com.google.inject.Inject;
import com.google.inject.Scopes;
/**
* @author Jan Koehnlein - Initial contribution and API
*/
public class WorkspaceFoldersTest extends AbstractTestLangLanguageServerTest {
@Inject
private UriExtensions uriExtensions;
@Inject
private WorkspaceManager workspaceManager;
@Rule
public TemporaryFolder temporaryFolder = new TemporaryFolder();
@Test
public void testInitialize() throws Exception {
File rootFolder1 = temporaryFolder.newFolder("root1");
File rootFolder2 = temporaryFolder.newFolder("root2");
writeFile(rootFolder1, "one.testlang", "type Foo { Bar bar }");
String twoUri = writeFile(rootFolder2, "two.testlang", "type Bar { Foo foo }");
initialize((InitializeParams it) -> {
it.setWorkspaceFolders(
Lists.newArrayList(new WorkspaceFolder(uriExtensions.toUriString(rootFolder1.toURI()), "root1"),
new WorkspaceFolder(uriExtensions.toUriString(rootFolder2.toURI()), "root2")));
});
Assert.assertEquals(2, getDiagnostics().size());
Assert.assertEquals(1, getDiagnostics().get(twoUri).size());
withBuild(() -> {
DidChangeWorkspaceFoldersParams didChangeWorkspaceFoldersParams = new DidChangeWorkspaceFoldersParams();
WorkspaceFoldersChangeEvent workspaceFoldersChangeEvent = new WorkspaceFoldersChangeEvent();
workspaceFoldersChangeEvent.setRemoved(
Lists.newArrayList(new WorkspaceFolder(uriExtensions.toUriString(rootFolder2.toURI()), "root2")));
didChangeWorkspaceFoldersParams.setEvent(workspaceFoldersChangeEvent);
languageServer.didChangeWorkspaceFolders(didChangeWorkspaceFoldersParams);
});
Assert.assertEquals(0, getDiagnostics().get(twoUri).size());
withBuild(() -> {
DidChangeWorkspaceFoldersParams didChangeWorkspaceFoldersParams = new DidChangeWorkspaceFoldersParams();
WorkspaceFoldersChangeEvent workspaceFoldersChangeEvent = new WorkspaceFoldersChangeEvent();
workspaceFoldersChangeEvent.setAdded(
Lists.newArrayList(new WorkspaceFolder(uriExtensions.toUriString(rootFolder2.toURI()), "root2")));
didChangeWorkspaceFoldersParams.setEvent(workspaceFoldersChangeEvent);
languageServer.didChangeWorkspaceFolders(didChangeWorkspaceFoldersParams);
});
Assert.assertEquals(1, getDiagnostics().get(twoUri).size());
}
protected void withBuild(Procedure0 lambda) throws Exception {
CompletableFuture<Void> future = new CompletableFuture<Void>();
workspaceManager.addBuildListener(new ILanguageServerAccess.IBuildListener() {
@Override
public void afterBuild(List<IResourceDescription.Delta> it) {
workspaceManager.removeBuildListener(this);
future.complete(null);
}
});
lambda.apply();
future.get();
}
public String writeFile(File root, String path, CharSequence contents) throws Exception {
File file = new File(root, path);
file.getParentFile().mkdirs();
file.createNewFile();
FileWriter writer = new FileWriter(file);
writer.write(contents.toString());
writer.close();
return uriExtensions.toUriString(file.toURI().normalize());
}
@Override
protected com.google.inject.Module getServerModule() {
com.google.inject.Module defaultModule = super.getServerModule();
com.google.inject.Module customModule = new AbstractModule() {
@Override
protected void configure() {
bind(WorkspaceManager.class).in(Scopes.SINGLETON);
}
};
return Modules2.mixin(defaultModule, customModule);
}
}

View file

@ -1,118 +0,0 @@
/*******************************************************************************
* Copyright (c) 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.ide.tests.server
import com.google.inject.AbstractModule
import com.google.inject.Inject
import com.google.inject.Module
import com.google.inject.Scopes
import java.io.File
import java.io.FileWriter
import java.util.concurrent.CompletableFuture
import org.eclipse.lsp4j.DidChangeWorkspaceFoldersParams
import org.eclipse.lsp4j.WorkspaceFolder
import org.eclipse.lsp4j.WorkspaceFoldersChangeEvent
import org.eclipse.xtext.ide.server.UriExtensions
import org.eclipse.xtext.ide.server.WorkspaceManager
import org.eclipse.xtext.util.Modules2
import org.junit.Rule
import org.junit.Test
import org.junit.rules.TemporaryFolder
import static org.junit.Assert.assertEquals
/**
* @author Jan Koehnlein - Initial contribution and API
*/
class WorkspaceFoldersTest extends AbstractTestLangLanguageServerTest {
@Inject extension UriExtensions
@Inject WorkspaceManager workspaceManager
@Rule
public TemporaryFolder temporaryFolder = new TemporaryFolder()
@Test
def void testInitialize() {
val rootFolder1 = temporaryFolder.newFolder('root1')
val rootFolder2 = temporaryFolder.newFolder('root2')
writeFile(rootFolder1, "one.testlang", '''
type Foo {
Bar bar
}
''')
val twoUri = writeFile(rootFolder2, "two.testlang", '''
type Bar {
Foo foo
}
''')
initialize[
workspaceFolders = #[
new WorkspaceFolder(rootFolder1.toURI.toUriString, 'root1'),
new WorkspaceFolder(rootFolder2.toURI.toUriString, 'root2')
]
]
assertEquals(2, diagnostics.size)
assertEquals(1, diagnostics.get(twoUri).size)
withBuild [
languageServer.didChangeWorkspaceFolders(new DidChangeWorkspaceFoldersParams => [
event = new WorkspaceFoldersChangeEvent => [
removed = #[
new WorkspaceFolder(rootFolder2.toURI.toUriString, 'root2')
]
]
])
]
assertEquals(0, diagnostics.get(twoUri).size)
withBuild [
languageServer.didChangeWorkspaceFolders(new DidChangeWorkspaceFoldersParams => [
event = new WorkspaceFoldersChangeEvent => [
added = #[
new WorkspaceFolder(rootFolder2.toURI.toUriString, 'root2')
]
]
])
]
assertEquals(1, diagnostics.get(twoUri).size)
}
protected def void withBuild(()=>void lambda) {
val future = new CompletableFuture<Void>()
workspaceManager.addBuildListener[
workspaceManager.removeBuildListener(self)
future.complete(null)
]
lambda.apply
future.get
}
def String writeFile(File root, String path, CharSequence contents) {
val file = new File(root, path)
file.parentFile.mkdirs
file.createNewFile
val writer = new FileWriter(file)
writer.write(contents.toString)
writer.close
return file.toURI.normalize.toUriString
}
override protected getServerModule() {
val defaultModule = super.getServerModule()
val Module customModule = new AbstractModule() {
override protected configure() {
bind(WorkspaceManager).in(Scopes.SINGLETON);
}
}
return Modules2.mixin(defaultModule, customModule)
}
}

View file

@ -0,0 +1,100 @@
/**
* Copyright (c) 2016, 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.ide.tests.server;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.eclipse.emf.common.util.URI;
import org.eclipse.xtext.ide.server.Document;
import org.eclipse.xtext.ide.server.ServerModule;
import org.eclipse.xtext.ide.server.UriExtensions;
import org.eclipse.xtext.ide.server.WorkspaceManager;
import org.eclipse.xtext.resource.XtextResource;
import org.eclipse.xtext.util.Files;
import org.eclipse.xtext.validation.Issue;
import org.eclipse.xtext.xbase.lib.IterableExtensions;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import com.google.common.collect.Lists;
import com.google.inject.Guice;
import com.google.inject.Inject;
import com.google.inject.Injector;
/**
* @author Sven Efftinge - Initial contribution and API
*/
public class WorkspaceManagerTest {
@Test
public void testDoRead() throws IOException {
String model =
"type Test {\n" +
" string foo\n" +
"}\n";
URI path = operator_mappedTo("MyType1.testlang", model);
workspaceManger.doBuild(Lists.newArrayList(path),
Collections.emptyList(), null);
String inMemContents =
"type Test {\n" +
" Test foo\n" +
"}\n";
workspaceManger.didOpen(path, 1, inMemContents).build(null);
Assert.assertEquals(inMemContents,
workspaceManger.doRead(path, (Document $0, XtextResource $1) -> $0.getContents()));
}
@Inject
protected WorkspaceManager workspaceManger;
@Inject
protected UriExtensions uriExtensions;
@Before
public void setup() throws FileNotFoundException {
Injector injector = Guice.createInjector(new ServerModule());
injector.injectMembers(this);
root = new File("./test-data/test-project");
if (!root.mkdirs()) {
Files.cleanFolder(root, null, true, false);
}
root.deleteOnExit();
workspaceManger.initialize(uriExtensions.withEmptyAuthority(URI.createFileURI(root.getAbsolutePath())),
(URI $0, Iterable<Issue> $1) -> diagnostics.put($0, IterableExtensions.toList($1)), null);
}
@After
public void cleanup() throws FileNotFoundException {
if (root.exists()) {
Files.cleanFolder(root, null, true, true);
}
}
protected Map<URI, List<Issue>> diagnostics = new HashMap<>();
protected File root;
public URI operator_mappedTo(String path, CharSequence contents) throws IOException {
File file = new File(root, path);
file.getParentFile().mkdirs();
file.createNewFile();
try(FileWriter fileWriter = new FileWriter(file)) {
fileWriter.write(contents.toString());
}
return URI.createFileURI(file.getAbsolutePath());
}
}

View file

@ -1,91 +0,0 @@
/*******************************************************************************
* Copyright (c) 2016, 2017 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.ide.tests.server
import com.google.inject.Guice
import com.google.inject.Inject
import java.io.File
import java.io.FileWriter
import java.util.List
import java.util.Map
import org.eclipse.emf.common.util.URI
import org.eclipse.xtext.ide.server.ServerModule
import org.eclipse.xtext.ide.server.UriExtensions
import org.eclipse.xtext.ide.server.WorkspaceManager
import org.eclipse.xtext.util.Files
import org.eclipse.xtext.validation.Issue
import org.junit.After
import org.junit.Assert
import org.junit.Before
import org.junit.Test
/**
* @author Sven Efftinge - Initial contribution and API
*/
class WorkspaceManagerTest {
@Test def void testDoRead() {
val path = 'MyType1.testlang' -> '''
type Test {
string foo
}
'''
workspaceManger.doBuild(#[path], emptyList, null)
val String inMemContents = '''
type Test {
Test foo
}
'''
workspaceManger.didOpen(path, 1, inMemContents).build(null)
Assert.assertEquals(inMemContents, workspaceManger.doRead(path, [$0.contents]))
}
@Inject protected WorkspaceManager workspaceManger
@Inject extension protected UriExtensions uriExtensions
@Before
def void setup() {
val injector = Guice.createInjector(new ServerModule())
injector.injectMembers(this)
// register notification callbacks
// create workingdir
root = new File("./test-data/test-project")
if (!root.mkdirs) {
Files.cleanFolder(root, null, true, false)
}
root.deleteOnExit
workspaceManger.initialize(URI.createFileURI(root.absolutePath).withEmptyAuthority, [diagnostics.put($0, $1.toList)], null)
}
@After
def void cleanup() {
if (root.exists) {
Files.cleanFolder(root, null, true, true)
}
}
protected Map<URI, List<Issue>> diagnostics = newHashMap()
protected File root
def URI ->(String path, CharSequence contents) {
val file = new File(root, path)
file.parentFile.mkdirs
file.createNewFile
new FileWriter(file) => [
write(contents.toString)
close
]
return URI.createFileURI(file.absolutePath)
}
}

View file

@ -0,0 +1,131 @@
/**
* Copyright (c) 2018, 2020 TypeFox 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.ide.tests.testlanguage.editor.syntaxcoloring;
import java.util.List;
import java.util.Set;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.xtext.ide.editor.syntaxcoloring.DefaultSemanticHighlightingCalculator;
import org.eclipse.xtext.ide.editor.syntaxcoloring.IHighlightedPositionAcceptor;
import org.eclipse.xtext.ide.tests.testlanguage.testLanguage.Operation;
import org.eclipse.xtext.ide.tests.testlanguage.testLanguage.Parameter;
import org.eclipse.xtext.ide.tests.testlanguage.testLanguage.PrimitiveType;
import org.eclipse.xtext.ide.tests.testlanguage.testLanguage.Property;
import org.eclipse.xtext.ide.tests.testlanguage.testLanguage.TestLanguagePackage;
import org.eclipse.xtext.ide.tests.testlanguage.testLanguage.TypeDeclaration;
import org.eclipse.xtext.ide.tests.testlanguage.testLanguage.TypeReference;
import org.eclipse.xtext.nodemodel.ICompositeNode;
import org.eclipse.xtext.nodemodel.ILeafNode;
import org.eclipse.xtext.nodemodel.INode;
import org.eclipse.xtext.nodemodel.util.NodeModelUtils;
import org.eclipse.xtext.util.CancelIndicator;
import org.eclipse.xtext.xbase.lib.IterableExtensions;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
public class SemanticHighlightingCalculatorImpl extends DefaultSemanticHighlightingCalculator {
private static final String IDENTIFIER_STYLE = "identifier";
private static final String PRIMITIVE_TYPE_STYLE = "primitiveType";
private static final String TYPE_STYLE = "type";
private static final String TYPE_DECLARATION_STYLE = "typeDeclaration";
private static final String PARAMETER_NAME_STYLE = "parameterName";
private static final String OP_BODY_STYLE = "opBody";
public static final Set<String> STYLES = Sets.newHashSet(IDENTIFIER_STYLE, PRIMITIVE_TYPE_STYLE, TYPE_STYLE,
TYPE_DECLARATION_STYLE, PARAMETER_NAME_STYLE, OP_BODY_STYLE);
@Override
protected boolean highlightElement(EObject object, IHighlightedPositionAcceptor acceptor,
CancelIndicator cancelIndicator) {
if (object instanceof Operation) {
return doHighlightOperation((Operation) object, acceptor);
} else if (object instanceof PrimitiveType) {
return doHighlightPrimitiveType((PrimitiveType) object, acceptor);
} else if (object instanceof Property) {
return doHighlightProperty((Property) object, acceptor);
} else if (object instanceof TypeDeclaration) {
return doHighlightTypeDeclaration((TypeDeclaration) object, acceptor);
} else if (object instanceof TypeReference) {
return doHighlightTypeReference((TypeReference) object, acceptor);
} else if (object instanceof Parameter) {
return doHighlightParameter((Parameter) object, acceptor);
} else {
return false;
}
}
protected boolean doHighlightProperty(Property it, IHighlightedPositionAcceptor acceptor) {
return doHighlightNode(acceptor, it, TestLanguagePackage.Literals.MEMBER__NAME, IDENTIFIER_STYLE);
}
protected boolean doHighlightOperation(Operation it, IHighlightedPositionAcceptor acceptor) {
boolean canStop = doHighlightNode(acceptor, it, TestLanguagePackage.Literals.MEMBER__NAME, IDENTIFIER_STYLE);
ICompositeNode opNode = NodeModelUtils.findActualNodeFor(it);
if (opNode != null) {
List<ILeafNode> inverseChildren = Lists.reverse(
Lists.newArrayList(Iterables.filter(opNode.getLeafNodes(), (ILeafNode n) -> !n.isHidden())));
int endOffset = -1;
int startOffset = -1;
ILeafNode first = Iterables.getFirst(inverseChildren, null);
String text = null;
if (first != null) {
text = first.getText();
}
if ("}".equals(text)) {
endOffset = first.getEndOffset() - 1;
}
if (endOffset != -1) {
ILeafNode opStartNode = IterableExtensions.findFirst(inverseChildren,
c -> "{".equals(c.getText().trim()));
if (opStartNode != null) {
startOffset = opStartNode.getOffset() + 1;
}
}
if (startOffset >= 0 && endOffset >= 0) {
acceptor.addPosition(startOffset, endOffset - startOffset, OP_BODY_STYLE);
}
}
return canStop;
}
protected boolean doHighlightTypeDeclaration(TypeDeclaration it, IHighlightedPositionAcceptor acceptor) {
return doHighlightNode(acceptor, it, TestLanguagePackage.Literals.ABSTRACT_ELEMENT__NAME,
TYPE_DECLARATION_STYLE);
}
protected boolean doHighlightPrimitiveType(PrimitiveType it, IHighlightedPositionAcceptor acceptor) {
return doHighlightNode(acceptor, it, TestLanguagePackage.Literals.PRIMITIVE_TYPE__NAME, PRIMITIVE_TYPE_STYLE);
}
protected boolean doHighlightTypeReference(TypeReference it, IHighlightedPositionAcceptor acceptor) {
return doHighlightNode(acceptor, it, TestLanguagePackage.Literals.TYPE_REFERENCE__TYPE_REF, TYPE_STYLE);
}
protected boolean doHighlightParameter(Parameter it, IHighlightedPositionAcceptor acceptor) {
return doHighlightNode(acceptor, it, TestLanguagePackage.Literals.PARAMETER__NAME, PARAMETER_NAME_STYLE);
}
public boolean doHighlightNode(IHighlightedPositionAcceptor acceptor, EObject object, EStructuralFeature feature,
String style) {
NodeModelUtils.findNodesForFeature(object, feature).forEach((INode it) -> {
acceptor.addPosition(it.getOffset(), it.getLength(), style);
});
return false;
}
}

View file

@ -1,108 +0,0 @@
/*******************************************************************************
* Copyright (c) 2018 TypeFox 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.ide.tests.testlanguage.editor.syntaxcoloring
import org.eclipse.emf.ecore.EObject
import org.eclipse.emf.ecore.EStructuralFeature
import org.eclipse.xtext.ide.editor.syntaxcoloring.DefaultSemanticHighlightingCalculator
import org.eclipse.xtext.ide.editor.syntaxcoloring.IHighlightedPositionAcceptor
import org.eclipse.xtext.ide.tests.testlanguage.testLanguage.Operation
import org.eclipse.xtext.ide.tests.testlanguage.testLanguage.Parameter
import org.eclipse.xtext.ide.tests.testlanguage.testLanguage.PrimitiveType
import org.eclipse.xtext.ide.tests.testlanguage.testLanguage.Property
import org.eclipse.xtext.ide.tests.testlanguage.testLanguage.TypeDeclaration
import org.eclipse.xtext.ide.tests.testlanguage.testLanguage.TypeReference
import org.eclipse.xtext.nodemodel.util.NodeModelUtils
import org.eclipse.xtext.util.CancelIndicator
import static org.eclipse.xtext.ide.tests.testlanguage.testLanguage.TestLanguagePackage.Literals.*
class SemanticHighlightingCalculatorImpl extends DefaultSemanticHighlightingCalculator {
static val IDENTIFIER_STYLE = 'identifier';
static val PRIMITIVE_TYPE_STYLE = 'primitiveType';
static val TYPE_STYLE = 'type';
static val TYPE_DECLARATION_STYLE = 'typeDeclaration';
static val PARAMETER_NAME_STYLE = 'parameterName';
static val OP_BODY_STYLE = 'opBody';
public static val STYLES = #{
IDENTIFIER_STYLE,
PRIMITIVE_TYPE_STYLE,
TYPE_STYLE,
TYPE_DECLARATION_STYLE,
PARAMETER_NAME_STYLE,
OP_BODY_STYLE
};
override protected highlightElement(EObject object, IHighlightedPositionAcceptor acceptor,
CancelIndicator cancelIndicator) {
return object.doHighlightElement(acceptor);
}
def dispatch boolean doHighlightElement(EObject it, IHighlightedPositionAcceptor acceptor) {
return false;
}
def dispatch boolean doHighlightElement(Property it, IHighlightedPositionAcceptor acceptor) {
return acceptor.doHighlightNode(it, MEMBER__NAME, IDENTIFIER_STYLE);
}
def dispatch boolean doHighlightElement(Operation it, IHighlightedPositionAcceptor acceptor) {
val canStop = acceptor.doHighlightNode(it, MEMBER__NAME, IDENTIFIER_STYLE);
// Besides highlighting the name of the operation, we highlight the body between the braces (exclusive)
// to ensure, we can map a single multi-line range into several corresponding highlighting tokens.
val opNode = NodeModelUtils.findActualNodeFor(it)
if (opNode !== null) {
val inverseChildren = opNode.leafNodes.filter[!hidden].toList.reverse;
var endOffset = -1;
var startOffset = -1;
if (inverseChildren.head?.text == '}') {
endOffset = inverseChildren.head.endOffset - 1; // exclusive
}
if (endOffset !== -1) {
val opStartNode = inverseChildren.findFirst[text.trim == '{'];
if (opStartNode !== null) {
startOffset = opStartNode.offset + 1; // exclusive
}
}
if (startOffset >= 0 && endOffset >= 0) {
acceptor.addPosition(startOffset, endOffset - startOffset, OP_BODY_STYLE);
}
}
return canStop;
}
def dispatch boolean doHighlightElement(TypeDeclaration it, IHighlightedPositionAcceptor acceptor) {
return acceptor.doHighlightNode(it, ABSTRACT_ELEMENT__NAME, TYPE_DECLARATION_STYLE);
}
def dispatch boolean doHighlightElement(PrimitiveType it, IHighlightedPositionAcceptor acceptor) {
return acceptor.doHighlightNode(it, PRIMITIVE_TYPE__NAME, PRIMITIVE_TYPE_STYLE);
}
def dispatch boolean doHighlightElement(TypeReference it, IHighlightedPositionAcceptor acceptor) {
return acceptor.doHighlightNode(it, TYPE_REFERENCE__TYPE_REF, TYPE_STYLE);
}
def dispatch boolean doHighlightElement(Parameter it, IHighlightedPositionAcceptor acceptor) {
return acceptor.doHighlightNode(it, PARAMETER__NAME, PARAMETER_NAME_STYLE);
}
def doHighlightNode(IHighlightedPositionAcceptor acceptor, EObject object, EStructuralFeature feature,
String style) {
NodeModelUtils.findNodesForFeature(object, feature).forEach [
acceptor.addPosition(offset, length, style)
];
return false;
}
}

View file

@ -1,50 +0,0 @@
/**
* Copyright (c) 2017 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.ide.tests.server;
import java.util.List;
import org.eclipse.lsp4j.CodeLens;
import org.eclipse.lsp4j.Position;
import org.eclipse.xtend2.lib.StringConcatenation;
import org.eclipse.xtext.ide.tests.server.AbstractTestLangLanguageServerTest;
import org.eclipse.xtext.testing.AbstractLanguageServerTest;
import org.eclipse.xtext.xbase.lib.IterableExtensions;
import org.eclipse.xtext.xbase.lib.Procedures.Procedure1;
import org.junit.Assert;
import org.junit.Test;
/**
* @author Sven Efftinge - Initial contribution and API
*/
@SuppressWarnings("all")
public class CodeLensTest extends AbstractTestLangLanguageServerTest {
@Test
public void testCodeLens() {
final Procedure1<AbstractLanguageServerTest.TestCodeLensConfiguration> _function = (AbstractLanguageServerTest.TestCodeLensConfiguration it) -> {
StringConcatenation _builder = new StringConcatenation();
_builder.append("type Foo {}");
_builder.newLine();
_builder.append("type Bar {");
_builder.newLine();
_builder.append("\t");
_builder.append("Foo foo");
_builder.newLine();
_builder.append("}");
_builder.newLine();
it.setModel(_builder.toString());
final Procedure1<List<? extends CodeLens>> _function_1 = (List<? extends CodeLens> it_1) -> {
this.assertEquals("Do Awesome Stuff(RESOLVED)", IterableExtensions.head(it_1).getCommand().getTitle());
Object _data = IterableExtensions.head(it_1).getData();
Assert.assertEquals(1, ((Position) _data).getLine());
};
it.setAssertCodeLenses(_function_1);
};
this.testCodeLens(_function);
}
}

View file

@ -1,143 +0,0 @@
/**
* Copyright (c) 2018 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.ide.tests.server;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.function.Consumer;
import org.eclipse.lsp4j.ClientCapabilities;
import org.eclipse.lsp4j.ExecuteCommandCapabilities;
import org.eclipse.lsp4j.ExecuteCommandParams;
import org.eclipse.lsp4j.InitializeParams;
import org.eclipse.lsp4j.WorkspaceClientCapabilities;
import org.eclipse.xtend.lib.annotations.Accessors;
import org.eclipse.xtext.ide.tests.server.AbstractTestLangLanguageServerTest;
import org.eclipse.xtext.xbase.lib.Exceptions;
import org.eclipse.xtext.xbase.lib.Extension;
import org.eclipse.xtext.xbase.lib.ObjectExtensions;
import org.eclipse.xtext.xbase.lib.Procedures.Procedure1;
import org.eclipse.xtext.xbase.lib.Pure;
import org.junit.Assert;
import org.junit.Test;
/**
* @author Christian Dietrich - Initial contribution and API
*/
@SuppressWarnings("all")
public class CommandServiceTest extends AbstractTestLangLanguageServerTest {
@Accessors
public static class TestExecuteCommandConfiguration {
private String command = "";
private List<Object> args = new ArrayList<Object>();
private Consumer<Object> assertCommandResult = null;
@Pure
public String getCommand() {
return this.command;
}
public void setCommand(final String command) {
this.command = command;
}
@Pure
public List<Object> getArgs() {
return this.args;
}
public void setArgs(final List<Object> args) {
this.args = args;
}
@Pure
public Consumer<Object> getAssertCommandResult() {
return this.assertCommandResult;
}
public void setAssertCommandResult(final Consumer<Object> assertCommandResult) {
this.assertCommandResult = assertCommandResult;
}
}
protected void testExecuteCommand(final Procedure1<? super CommandServiceTest.TestExecuteCommandConfiguration> configurator) {
try {
@Extension
final CommandServiceTest.TestExecuteCommandConfiguration configuration = new CommandServiceTest.TestExecuteCommandConfiguration();
configurator.apply(configuration);
final String command = configuration.command;
final List<Object> args = configuration.args;
ExecuteCommandParams _executeCommandParams = new ExecuteCommandParams(command, args);
final CompletableFuture<Object> result = this.languageServer.executeCommand(_executeCommandParams);
if ((configuration.assertCommandResult != null)) {
final Object value = result.get();
configuration.assertCommandResult.accept(value);
}
} catch (Throwable _e) {
throw Exceptions.sneakyThrow(_e);
}
}
@Test
public void testExecute() {
final Procedure1<InitializeParams> _function = (InitializeParams it) -> {
ClientCapabilities _clientCapabilities = new ClientCapabilities();
final Procedure1<ClientCapabilities> _function_1 = (ClientCapabilities it_1) -> {
WorkspaceClientCapabilities _workspaceClientCapabilities = new WorkspaceClientCapabilities();
final Procedure1<WorkspaceClientCapabilities> _function_2 = (WorkspaceClientCapabilities it_2) -> {
ExecuteCommandCapabilities _executeCommandCapabilities = new ExecuteCommandCapabilities();
final Procedure1<ExecuteCommandCapabilities> _function_3 = (ExecuteCommandCapabilities it_3) -> {
it_3.setDynamicRegistration(Boolean.valueOf(true));
};
ExecuteCommandCapabilities _doubleArrow = ObjectExtensions.<ExecuteCommandCapabilities>operator_doubleArrow(_executeCommandCapabilities, _function_3);
it_2.setExecuteCommand(_doubleArrow);
};
WorkspaceClientCapabilities _doubleArrow = ObjectExtensions.<WorkspaceClientCapabilities>operator_doubleArrow(_workspaceClientCapabilities, _function_2);
it_1.setWorkspace(_doubleArrow);
};
ClientCapabilities _doubleArrow = ObjectExtensions.<ClientCapabilities>operator_doubleArrow(_clientCapabilities, _function_1);
it.setCapabilities(_doubleArrow);
};
this.initialize(_function);
final Procedure1<CommandServiceTest.TestExecuteCommandConfiguration> _function_1 = (CommandServiceTest.TestExecuteCommandConfiguration it) -> {
it.command = "testlang.a";
final Consumer<Object> _function_2 = (Object it_1) -> {
if ((it_1 instanceof String)) {
this.assertEquals("a", ((String)it_1));
} else {
Assert.fail("no string");
}
};
it.assertCommandResult = _function_2;
};
this.testExecuteCommand(_function_1);
final Procedure1<CommandServiceTest.TestExecuteCommandConfiguration> _function_2 = (CommandServiceTest.TestExecuteCommandConfiguration it) -> {
it.command = "testlang.b";
final Consumer<Object> _function_3 = (Object it_1) -> {
if ((it_1 instanceof String)) {
this.assertEquals("b", ((String)it_1));
} else {
Assert.fail("no string");
}
};
it.assertCommandResult = _function_3;
};
this.testExecuteCommand(_function_2);
final Procedure1<CommandServiceTest.TestExecuteCommandConfiguration> _function_3 = (CommandServiceTest.TestExecuteCommandConfiguration it) -> {
it.command = "doesnotexist.c";
final Consumer<Object> _function_4 = (Object it_1) -> {
Assert.assertNull(it_1);
};
it.assertCommandResult = _function_4;
};
this.testExecuteCommand(_function_3);
}
}

View file

@ -1,45 +0,0 @@
/**
* Copyright (c) 2016 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.ide.tests.server;
import org.eclipse.xtend2.lib.StringConcatenation;
import org.eclipse.xtext.ide.tests.server.AbstractTestLangLanguageServerTest;
import org.eclipse.xtext.testing.DefinitionTestConfiguration;
import org.eclipse.xtext.xbase.lib.Procedures.Procedure1;
import org.junit.Test;
/**
* @author kosyakov - Initial contribution and API
*/
@SuppressWarnings("all")
public class DefinitionTest extends AbstractTestLangLanguageServerTest {
@Test
public void testDefinition_01() {
final Procedure1<DefinitionTestConfiguration> _function = (DefinitionTestConfiguration it) -> {
StringConcatenation _builder = new StringConcatenation();
_builder.append("type Foo {}");
_builder.newLine();
_builder.append("type Bar {");
_builder.newLine();
_builder.append("\t");
_builder.append("Foo foo");
_builder.newLine();
_builder.append("}");
_builder.newLine();
it.setModel(_builder.toString());
it.setLine(2);
it.setColumn(3);
StringConcatenation _builder_1 = new StringConcatenation();
_builder_1.append("MyModel.testlang [[0, 5] .. [0, 8]]");
_builder_1.newLine();
it.setExpectedDefinitions(_builder_1.toString());
};
this.testDefinition(_function);
}
}

View file

@ -1,208 +0,0 @@
/**
* Copyright (c) 2016 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.ide.tests.server;
import org.eclipse.lsp4j.DocumentHighlight;
import org.eclipse.lsp4j.DocumentHighlightKind;
import org.eclipse.lsp4j.Position;
import org.eclipse.xtend2.lib.StringConcatenation;
import org.eclipse.xtext.ide.server.occurrences.IDocumentHighlightService;
import org.eclipse.xtext.ide.tests.server.AbstractTestLangLanguageServerTest;
import org.eclipse.xtext.testing.DocumentHighlightConfiguration;
import org.eclipse.xtext.xbase.lib.Procedures.Procedure1;
import org.junit.Test;
/**
* Class for testing the {@link DocumentHighlightService document highlight
* service} behavior through the language server.
*
* <p>
* The string representation of on single {@link DocumentHighlight highlight}
* instance is represented with the below pattern:
*
* <pre>
* R|W|T [{d}+, {d}+] .. [{d}+, {d}+]
* </pre>
*
* where the first character describes the {@link DocumentHighlightKind kind} of
* the document highlight. If missing, then the value is {@code NaN}. The values
* between the first square brackets are the start {@link Position#getLine()
* line} and the (zero-based) {@link Position#getCharacter() character offset}
* in the line. The second square brackets contains the end position of the
* selection and described with the same semantics as the first start range.
* Multiple highlight instances are separated by the {@code |} ("pipe")
* character.
*
* @author akos.kitta - Initial contribution and API
*
* @see DocumentHighlight
* @see IDocumentHighlightService
*/
@SuppressWarnings("all")
public class DocumentHighlightTest extends AbstractTestLangLanguageServerTest {
@Test
public void singleLineNoOccurrences_SelectionBeforeWriteSiteMethodName() {
final Procedure1<DocumentHighlightConfiguration> _function = (DocumentHighlightConfiguration it) -> {
StringConcatenation _builder = new StringConcatenation();
_builder.append("type A { op foo() { } }");
it.setModel(_builder.toString());
StringConcatenation _builder_1 = new StringConcatenation();
_builder_1.append("type A { op");
it.setColumn(_builder_1.length());
it.setExpectedDocumentHighlight("");
};
this.testDocumentHighlight(_function);
}
@Test
public void singleLineNoOccurrences_SelectionAfterWriteSiteMethodName() {
final Procedure1<DocumentHighlightConfiguration> _function = (DocumentHighlightConfiguration it) -> {
StringConcatenation _builder = new StringConcatenation();
_builder.append("type A { op foo() { } }");
it.setModel(_builder.toString());
StringConcatenation _builder_1 = new StringConcatenation();
_builder_1.append("type A { op foo(");
it.setColumn(_builder_1.length());
it.setExpectedDocumentHighlight("");
};
this.testDocumentHighlight(_function);
}
@Test
public void singleLineSingleOccurrence() {
final Procedure1<DocumentHighlightConfiguration> _function = (DocumentHighlightConfiguration it) -> {
StringConcatenation _builder = new StringConcatenation();
_builder.append("type A { op foo() { } }");
it.setModel(_builder.toString());
StringConcatenation _builder_1 = new StringConcatenation();
_builder_1.append("type A { op fo");
it.setColumn(_builder_1.length());
it.setExpectedDocumentHighlight("W [[0, 12] .. [0, 15]]");
};
this.testDocumentHighlight(_function);
}
@Test
public void singleLineSingleOccurrenceWithVariable() {
final Procedure1<DocumentHighlightConfiguration> _function = (DocumentHighlightConfiguration it) -> {
StringConcatenation _builder = new StringConcatenation();
_builder.append("type A { int foo op foo() { } }");
it.setModel(_builder.toString());
StringConcatenation _builder_1 = new StringConcatenation();
_builder_1.append("type A { int fo");
it.setColumn(_builder_1.length());
it.setExpectedDocumentHighlight("W [[0, 13] .. [0, 16]]");
};
this.testDocumentHighlight(_function);
}
@Test
public void singleLineSingleOccurrenceWithMultipleTypes() {
final Procedure1<DocumentHighlightConfiguration> _function = (DocumentHighlightConfiguration it) -> {
StringConcatenation _builder = new StringConcatenation();
_builder.append("type A { op foo() { } } type B { op foo() { } }");
it.setModel(_builder.toString());
StringConcatenation _builder_1 = new StringConcatenation();
_builder_1.append("type A { op fo");
it.setColumn(_builder_1.length());
it.setExpectedDocumentHighlight("W [[0, 12] .. [0, 15]]");
};
this.testDocumentHighlight(_function);
}
@Test
public void singleLineMultipleOccurrences_SelectionOnReadSite() {
final Procedure1<DocumentHighlightConfiguration> _function = (DocumentHighlightConfiguration it) -> {
StringConcatenation _builder = new StringConcatenation();
_builder.append("type A { op foo() { } op bar() { foo(10) } }");
it.setModel(_builder.toString());
it.setLine(0);
StringConcatenation _builder_1 = new StringConcatenation();
_builder_1.append("type A { op foo() { } op bar() { fo");
it.setColumn(_builder_1.length());
it.setExpectedDocumentHighlight("W [[0, 12] .. [0, 15]] | R [[0, 33] .. [0, 36]]");
};
this.testDocumentHighlight(_function);
}
@Test
public void singleLineMultipleOccurrences_SelectionOnWriteSite() {
final Procedure1<DocumentHighlightConfiguration> _function = (DocumentHighlightConfiguration it) -> {
StringConcatenation _builder = new StringConcatenation();
_builder.append("type A { op foo() { } op bar() { foo(10) } }");
it.setModel(_builder.toString());
it.setLine(0);
StringConcatenation _builder_1 = new StringConcatenation();
_builder_1.append("type A { op fo");
it.setColumn(_builder_1.length());
it.setExpectedDocumentHighlight("W [[0, 12] .. [0, 15]] | R [[0, 33] .. [0, 36]]");
};
this.testDocumentHighlight(_function);
}
@Test
public void multipleLinesMultipleOccurrences_WithHorizontalTabs() {
final Procedure1<DocumentHighlightConfiguration> _function = (DocumentHighlightConfiguration it) -> {
StringConcatenation _builder = new StringConcatenation();
_builder.append("type A {");
_builder.newLine();
_builder.append("\t");
_builder.append("op foo() { }");
_builder.newLine();
_builder.append("\t");
_builder.append("op bar() {");
_builder.newLine();
_builder.append("\t\t");
_builder.append("foo(10)");
_builder.newLine();
_builder.append("\t");
_builder.append("}");
_builder.newLine();
_builder.append("}");
it.setModel(_builder.toString());
it.setLine(1);
StringConcatenation _builder_1 = new StringConcatenation();
_builder_1.append("\t");
_builder_1.append("op fo");
it.setColumn(_builder_1.length());
it.setExpectedDocumentHighlight("W [[1, 4] .. [1, 7]] | R [[3, 2] .. [3, 5]]");
};
this.testDocumentHighlight(_function);
}
@Test
public void multipleLinesMultipleOccurrences_WithWhitespaces() {
final Procedure1<DocumentHighlightConfiguration> _function = (DocumentHighlightConfiguration it) -> {
StringConcatenation _builder = new StringConcatenation();
_builder.append("type A {");
_builder.newLine();
_builder.append(" ");
_builder.append("op foo() { }");
_builder.newLine();
_builder.append(" ");
_builder.append("op bar() {");
_builder.newLine();
_builder.append(" ");
_builder.append("foo(10)");
_builder.newLine();
_builder.append(" ");
_builder.append("}");
_builder.newLine();
_builder.append("}");
it.setModel(_builder.toString());
it.setLine(1);
StringConcatenation _builder_1 = new StringConcatenation();
_builder_1.append(" ");
_builder_1.append("op fo");
it.setColumn(_builder_1.length());
it.setExpectedDocumentHighlight("W [[1, 7] .. [1, 10]] | R [[3, 8] .. [3, 11]]");
};
this.testDocumentHighlight(_function);
}
}

View file

@ -1,57 +0,0 @@
/**
* Copyright (c) 2019 Sigasi N.V. (http://www.sigasi.com) 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.ide.tests.server;
import org.eclipse.xtend2.lib.StringConcatenation;
import org.eclipse.xtext.testing.AbstractLanguageServerTest;
import org.eclipse.xtext.testing.DocumentHighlightConfiguration;
import org.eclipse.xtext.xbase.lib.Procedures.Procedure1;
import org.junit.Test;
/**
* Class for testing the highlighting of reference that refer to the object in which they are embedded.
*/
@SuppressWarnings("all")
public class DocumentHighlightTest2 extends AbstractLanguageServerTest {
public DocumentHighlightTest2() {
super("nestedRefs");
}
@Test
public void testHighlightDeclarationWithNestedReference() {
final Procedure1<DocumentHighlightConfiguration> _function = (DocumentHighlightConfiguration it) -> {
StringConcatenation _builder = new StringConcatenation();
_builder.append("decl myDecl end myDecl;");
_builder.newLine();
it.setModel(_builder.toString());
it.setLine(0);
StringConcatenation _builder_1 = new StringConcatenation();
_builder_1.append("decl myDec");
it.setColumn(_builder_1.length());
it.setExpectedDocumentHighlight("W [[0, 5] .. [0, 11]] | R [[0, 16] .. [0, 22]]");
};
this.testDocumentHighlight(_function);
}
@Test
public void testHighlightNestedReferenceInsideDeclaration() {
final Procedure1<DocumentHighlightConfiguration> _function = (DocumentHighlightConfiguration it) -> {
StringConcatenation _builder = new StringConcatenation();
_builder.append("decl myDecl end myDecl;");
_builder.newLine();
it.setModel(_builder.toString());
it.setLine(0);
StringConcatenation _builder_1 = new StringConcatenation();
_builder_1.append("decl myDecl end myDe");
it.setColumn(_builder_1.length());
it.setExpectedDocumentHighlight("W [[0, 5] .. [0, 11]] | R [[0, 16] .. [0, 22]]");
};
this.testDocumentHighlight(_function);
}
}

View file

@ -1,166 +0,0 @@
/**
* Copyright (c) 2019 NumberFour AG (http://www.enfore.com) 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.ide.tests.server;
import com.google.inject.Binder;
import com.google.inject.binder.AnnotatedBindingBuilder;
import java.io.File;
import java.util.Collections;
import java.util.Set;
import org.eclipse.emf.common.util.URI;
import org.eclipse.lsp4j.DidChangeWatchedFilesParams;
import org.eclipse.lsp4j.FileChangeType;
import org.eclipse.lsp4j.FileEvent;
import org.eclipse.lsp4j.WorkspaceFolder;
import org.eclipse.lsp4j.services.WorkspaceService;
import org.eclipse.xtend2.lib.StringConcatenation;
import org.eclipse.xtext.ide.server.IMultiRootWorkspaceConfigFactory;
import org.eclipse.xtext.ide.server.MultiRootWorkspaceConfigFactory;
import org.eclipse.xtext.ide.server.ServerModule;
import org.eclipse.xtext.ide.tests.server.AbstractTestLangLanguageServerTest;
import org.eclipse.xtext.testing.ReferenceTestConfiguration;
import org.eclipse.xtext.util.Modules2;
import org.eclipse.xtext.workspace.FileProjectConfig;
import org.eclipse.xtext.workspace.WorkspaceConfig;
import org.eclipse.xtext.xbase.lib.CollectionLiterals;
import org.eclipse.xtext.xbase.lib.IterableExtensions;
import org.eclipse.xtext.xbase.lib.Procedures.Procedure1;
import org.junit.Assert;
import org.junit.Test;
/**
* Checks functionality of method IProjectConfig#isIndexOnly()
*
* @author Marcus Mews - Initial contribution and API
*/
@SuppressWarnings("all")
public class IndexOnlyProjectTest extends AbstractTestLangLanguageServerTest {
@Override
public com.google.inject.Module getServerModule() {
ServerModule _serverModule = new ServerModule();
final com.google.inject.Module _function = (Binder it) -> {
AnnotatedBindingBuilder<IMultiRootWorkspaceConfigFactory> _bind = it.<IMultiRootWorkspaceConfigFactory>bind(IMultiRootWorkspaceConfigFactory.class);
_bind.toInstance(new MultiRootWorkspaceConfigFactory() {
@Override
public void addProjectsForWorkspaceFolder(final WorkspaceConfig workspaceConfig, final WorkspaceFolder workspaceFolder, final Set<String> existingNames) {
String _uri = null;
if (workspaceFolder!=null) {
_uri=workspaceFolder.getUri();
}
boolean _tripleNotEquals = (_uri != null);
if (_tripleNotEquals) {
URI _uri_1 = this.getUriExtensions().toUri(workspaceFolder.getUri());
String _uniqueProjectName = this.getUniqueProjectName(workspaceFolder.getName(), existingNames);
final FileProjectConfig project = new FileProjectConfig(_uri_1, _uniqueProjectName) {
@Override
public boolean isIndexOnly() {
return true;
}
};
project.addSourceFolder(".");
workspaceConfig.addProject(project);
}
}
});
};
return Modules2.mixin(_serverModule, _function);
}
/**
* Shows that the resource is indexed
*/
@Test
public void testIndexByUsingReferences() {
final Procedure1<ReferenceTestConfiguration> _function = (ReferenceTestConfiguration it) -> {
StringConcatenation _builder = new StringConcatenation();
_builder.append("type Foo {}");
_builder.newLine();
_builder.append("type Bar {");
_builder.newLine();
_builder.append("\t");
_builder.append("Foo foo");
_builder.newLine();
_builder.append("}");
_builder.newLine();
it.setModel(_builder.toString());
it.setColumn("type F".length());
StringConcatenation _builder_1 = new StringConcatenation();
_builder_1.append("MyModel.testlang [[2, 1] .. [2, 4]]");
_builder_1.newLine();
it.setExpectedReferences(_builder_1.toString());
};
this.testReferences(_function);
}
/**
* Shows that the resource is not validated during initial build
*/
@Test
public void testInitializeBuildNoValidation() {
StringConcatenation _builder = new StringConcatenation();
_builder.append("type Test {");
_builder.newLine();
_builder.append(" ");
_builder.append("NonExisting foo");
_builder.newLine();
_builder.append("}");
_builder.newLine();
this.writeFile("MyType1.testlang", _builder);
this.initialize();
Assert.assertTrue(IterableExtensions.join(this.getDiagnostics().entrySet(), ","), this.getDiagnostics().isEmpty());
}
/**
* Shows that the error-free resource is not generated during initial build
*/
@Test
public void testInitializeBuildNoGeneration() {
StringConcatenation _builder = new StringConcatenation();
_builder.append("type TestType {");
_builder.newLine();
_builder.append(" ");
_builder.append("int foo");
_builder.newLine();
_builder.append("}");
_builder.newLine();
this.writeFile("MyType1.testlang", _builder);
this.initialize();
final File outputFile = new File(this.root, "src-gen/TestType.java");
Assert.assertFalse(IterableExtensions.join(this.getDiagnostics().entrySet(), ","), outputFile.isFile());
}
/**
* Shows that the resource is not validated during incremental build
*/
@Test
public void testIncrementalBuildNoValidation() {
StringConcatenation _builder = new StringConcatenation();
_builder.append("type Test {");
_builder.newLine();
_builder.append(" ");
_builder.append("NonExisting foo");
_builder.newLine();
_builder.append("}");
_builder.newLine();
this.writeFile("MyType1.testlang", _builder);
this.initialize();
Assert.assertTrue(IterableExtensions.join(this.getDiagnostics().entrySet(), ","), this.getDiagnostics().isEmpty());
StringConcatenation _builder_1 = new StringConcatenation();
_builder_1.append("type NonExisting {");
_builder_1.newLine();
_builder_1.append("}");
_builder_1.newLine();
final String path = this.writeFile("MyType2.testlang", _builder_1);
WorkspaceService _workspaceService = this.languageServer.getWorkspaceService();
FileEvent _fileEvent = new FileEvent(path, FileChangeType.Created);
DidChangeWatchedFilesParams _didChangeWatchedFilesParams = new DidChangeWatchedFilesParams(Collections.<FileEvent>unmodifiableList(CollectionLiterals.<FileEvent>newArrayList(_fileEvent)));
_workspaceService.didChangeWatchedFiles(_didChangeWatchedFilesParams);
Assert.assertTrue(IterableExtensions.join(this.getDiagnostics().entrySet(), ","), this.getDiagnostics().isEmpty());
}
}

View file

@ -1,113 +0,0 @@
/**
* Copyright (c) 2016 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.ide.tests.server;
import com.google.common.collect.Iterables;
import java.util.Collections;
import java.util.List;
import org.eclipse.lsp4j.DidOpenTextDocumentParams;
import org.eclipse.lsp4j.TextDocumentItem;
import org.eclipse.lsp4j.jsonrpc.services.ServiceEndpoints;
import org.eclipse.xtend2.lib.StringConcatenation;
import org.eclipse.xtext.ide.tests.server.AbstractTestLangLanguageServerTest;
import org.eclipse.xtext.ide.tests.testlanguage.ide.TestLangLSPExtension;
import org.eclipse.xtext.xbase.lib.CollectionLiterals;
import org.eclipse.xtext.xbase.lib.Exceptions;
import org.eclipse.xtext.xbase.lib.Functions.Function1;
import org.eclipse.xtext.xbase.lib.IterableExtensions;
import org.eclipse.xtext.xbase.lib.ListExtensions;
import org.eclipse.xtext.xbase.lib.ObjectExtensions;
import org.eclipse.xtext.xbase.lib.Pair;
import org.eclipse.xtext.xbase.lib.Procedures.Procedure1;
import org.junit.Assert;
import org.junit.Test;
/**
* @author efftinge - Initial contribution and API
*/
@SuppressWarnings("all")
public class LspExtensionTest extends AbstractTestLangLanguageServerTest {
@Test
public void testExtension() {
try {
final String fileURI = this.writeFile("mydoc.testlang", "");
this.initialize();
final TestLangLSPExtension ext = ServiceEndpoints.<TestLangLSPExtension>toServiceObject(this.languageServer, TestLangLSPExtension.class);
DidOpenTextDocumentParams _didOpenTextDocumentParams = new DidOpenTextDocumentParams();
final Procedure1<DidOpenTextDocumentParams> _function = (DidOpenTextDocumentParams it) -> {
TextDocumentItem _textDocumentItem = new TextDocumentItem();
final Procedure1<TextDocumentItem> _function_1 = (TextDocumentItem it_1) -> {
it_1.setUri(fileURI);
StringConcatenation _builder = new StringConcatenation();
_builder.append("foo bar");
_builder.newLine();
_builder.append("baz test");
_builder.newLine();
_builder.append("\t");
_builder.append("bla blubb");
_builder.newLine();
it_1.setText(_builder.toString());
};
TextDocumentItem _doubleArrow = ObjectExtensions.<TextDocumentItem>operator_doubleArrow(_textDocumentItem, _function_1);
it.setTextDocument(_doubleArrow);
};
DidOpenTextDocumentParams _doubleArrow = ObjectExtensions.<DidOpenTextDocumentParams>operator_doubleArrow(_didOpenTextDocumentParams, _function);
this.languageServer.didOpen(_doubleArrow);
TestLangLSPExtension.TextOfLineParam _textOfLineParam = new TestLangLSPExtension.TextOfLineParam();
final Procedure1<TestLangLSPExtension.TextOfLineParam> _function_1 = (TestLangLSPExtension.TextOfLineParam it) -> {
it.uri = fileURI;
it.line = 1;
};
TestLangLSPExtension.TextOfLineParam _doubleArrow_1 = ObjectExtensions.<TestLangLSPExtension.TextOfLineParam>operator_doubleArrow(_textOfLineParam, _function_1);
final TestLangLSPExtension.TextOfLineResult result = ext.getTextOfLine(_doubleArrow_1).get();
Assert.assertEquals("baz test", result.text);
final Function1<Pair<String, Object>, Object> _function_2 = (Pair<String, Object> it) -> {
return it.getValue();
};
Assert.assertEquals(2, IterableExtensions.size(Iterables.<TestLangLSPExtension.BuildNotification>filter(ListExtensions.<Pair<String, Object>, Object>map(this.notifications, _function_2), TestLangLSPExtension.BuildNotification.class)));
} catch (Throwable _e) {
throw Exceptions.sneakyThrow(_e);
}
}
@Test
public void testExtension_readIndex() {
try {
StringConcatenation _builder = new StringConcatenation();
_builder.append("type C {");
_builder.newLine();
_builder.append(" ");
_builder.append("op baz() { }");
_builder.newLine();
_builder.append("}");
_builder.newLine();
_builder.append("type A {");
_builder.newLine();
_builder.append(" ");
_builder.append("op foo() { }");
_builder.newLine();
_builder.append("}");
_builder.newLine();
_builder.append("type B {");
_builder.newLine();
_builder.append(" ");
_builder.append("op bar() { }");
_builder.newLine();
_builder.append("}");
_builder.newLine();
this.writeFile("model.testlang", _builder);
this.initialize();
final TestLangLSPExtension ext = ServiceEndpoints.<TestLangLSPExtension>toServiceObject(this.languageServer, TestLangLSPExtension.class);
final List<String> actual = IterableExtensions.<String>sort(IterableExtensions.<String>toList(ext.getAllOpNames().get()));
Assert.assertEquals(Collections.<String>unmodifiableList(CollectionLiterals.<String>newArrayList("bar", "baz", "foo")), actual);
} catch (Throwable _e) {
throw Exceptions.sneakyThrow(_e);
}
}
}

View file

@ -1,149 +0,0 @@
/**
* Copyright (c) 2016, 2017 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.ide.tests.server;
import com.google.inject.AbstractModule;
import com.google.inject.Guice;
import com.google.inject.Inject;
import com.google.inject.Injector;
import java.io.File;
import java.io.FileWriter;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import org.eclipse.emf.common.util.URI;
import org.eclipse.xtend2.lib.StringConcatenation;
import org.eclipse.xtext.diagnostics.Diagnostic;
import org.eclipse.xtext.ide.server.IMultiRootWorkspaceConfigFactory;
import org.eclipse.xtext.ide.server.MultiProjectWorkspaceConfigFactory;
import org.eclipse.xtext.ide.server.ServerModule;
import org.eclipse.xtext.ide.server.WorkspaceManager;
import org.eclipse.xtext.util.CancelIndicator;
import org.eclipse.xtext.util.Files;
import org.eclipse.xtext.util.Modules2;
import org.eclipse.xtext.validation.Issue;
import org.eclipse.xtext.xbase.lib.CollectionLiterals;
import org.eclipse.xtext.xbase.lib.Exceptions;
import org.eclipse.xtext.xbase.lib.IterableExtensions;
import org.eclipse.xtext.xbase.lib.ObjectExtensions;
import org.eclipse.xtext.xbase.lib.Procedures.Procedure1;
import org.eclipse.xtext.xbase.lib.Procedures.Procedure2;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
/**
* @author Jan Koehnlein - Initial contribution and API
*/
@SuppressWarnings("all")
public class MultiProjectTest {
private File project0;
private File project1;
private Map<URI, List<Issue>> diagnostics = CollectionLiterals.<URI, List<Issue>>newHashMap();
@Inject
private WorkspaceManager workspaceManager;
@Test
public void testCrossProjectLink() {
StringConcatenation _builder = new StringConcatenation();
_builder.append("type Foo {");
_builder.newLine();
_builder.append(" ");
_builder.append("Bar bar");
_builder.newLine();
_builder.append("}");
_builder.newLine();
final URI foo = this.createFile(this.project0, "Foo.testlang", _builder);
StringConcatenation _builder_1 = new StringConcatenation();
_builder_1.append("type Bar {");
_builder_1.newLine();
_builder_1.append("}");
_builder_1.newLine();
final URI bar = this.createFile(this.project1, "Bar.testlang", _builder_1);
this.workspaceManager.doBuild(Collections.<URI>unmodifiableList(CollectionLiterals.<URI>newArrayList(foo, bar)), CollectionLiterals.<URI>emptyList(), CancelIndicator.NullImpl);
Assert.assertEquals(2, this.diagnostics.size());
Assert.assertEquals(1, this.diagnostics.get(foo).size());
Assert.assertEquals(Diagnostic.LINKING_DIAGNOSTIC, IterableExtensions.<Issue>head(this.diagnostics.get(foo)).getCode());
Assert.assertTrue(this.diagnostics.get(bar).isEmpty());
this.diagnostics.clear();
List<String> _dependencies = this.workspaceManager.getProjectManager(this.project0.getName()).getProjectDescription().getDependencies();
String _name = this.project1.getName();
_dependencies.add(_name);
this.workspaceManager.doBuild(Collections.<URI>unmodifiableList(CollectionLiterals.<URI>newArrayList(foo, bar)), CollectionLiterals.<URI>emptyList(), CancelIndicator.NullImpl);
Assert.assertEquals(2, this.diagnostics.size());
Assert.assertTrue(this.diagnostics.get(foo).isEmpty());
Assert.assertTrue(this.diagnostics.get(bar).isEmpty());
}
@Before
public void setup() {
ServerModule _serverModule = new ServerModule();
final Injector injector = Guice.createInjector(Modules2.mixin(_serverModule, new AbstractModule() {
@Override
protected void configure() {
this.<IMultiRootWorkspaceConfigFactory>bind(IMultiRootWorkspaceConfigFactory.class).to(MultiProjectWorkspaceConfigFactory.class);
}
}));
injector.injectMembers(this);
final File workspaceRoot = this.getRoot("test-data");
File _file = new File(workspaceRoot, "test-project0");
this.project0 = _file;
File _file_1 = new File(workspaceRoot, "test-project1");
this.project1 = _file_1;
this.project0.mkdir();
this.project1.mkdir();
final Procedure2<URI, Iterable<Issue>> _function = (URI $0, Iterable<Issue> $1) -> {
this.diagnostics.put($0, IterableExtensions.<Issue>toList($1));
};
this.workspaceManager.initialize(URI.createFileURI(workspaceRoot.getAbsolutePath()), _function, null);
}
protected File getRoot(final String path) {
try {
File _xblockexpression = null;
{
final File root = new File(path);
boolean _mkdirs = root.mkdirs();
boolean _not = (!_mkdirs);
if (_not) {
Files.cleanFolder(root, null, true, false);
}
root.deleteOnExit();
_xblockexpression = root;
}
return _xblockexpression;
} catch (Throwable _e) {
throw Exceptions.sneakyThrow(_e);
}
}
public URI createFile(final File root, final String path, final CharSequence contents) {
try {
final File file = new File(root, path);
file.getParentFile().mkdirs();
file.createNewFile();
FileWriter _fileWriter = new FileWriter(file);
final Procedure1<FileWriter> _function = (FileWriter it) -> {
try {
it.write(contents.toString());
it.close();
} catch (Throwable _e) {
throw Exceptions.sneakyThrow(_e);
}
};
ObjectExtensions.<FileWriter>operator_doubleArrow(_fileWriter, _function);
return URI.createFileURI(file.getAbsolutePath());
} catch (Throwable _e) {
throw Exceptions.sneakyThrow(_e);
}
}
}

View file

@ -1,173 +0,0 @@
/**
* Copyright (c) 2016, 2017 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.ide.tests.server;
import java.util.Collections;
import org.eclipse.lsp4j.Diagnostic;
import org.eclipse.lsp4j.DidChangeTextDocumentParams;
import org.eclipse.lsp4j.DidChangeWatchedFilesParams;
import org.eclipse.lsp4j.FileChangeType;
import org.eclipse.lsp4j.FileEvent;
import org.eclipse.lsp4j.Position;
import org.eclipse.lsp4j.Range;
import org.eclipse.lsp4j.TextDocumentContentChangeEvent;
import org.eclipse.lsp4j.VersionedTextDocumentIdentifier;
import org.eclipse.lsp4j.services.WorkspaceService;
import org.eclipse.xtend2.lib.StringConcatenation;
import org.eclipse.xtext.ide.tests.server.AbstractTestLangLanguageServerTest;
import org.eclipse.xtext.xbase.lib.CollectionLiterals;
import org.eclipse.xtext.xbase.lib.IterableExtensions;
import org.eclipse.xtext.xbase.lib.ObjectExtensions;
import org.eclipse.xtext.xbase.lib.Procedures.Procedure1;
import org.junit.Assert;
import org.junit.Test;
/**
* @author Sven Efftinge - Initial contribution and API
*/
@SuppressWarnings("all")
public class OpenDocumentTest extends AbstractTestLangLanguageServerTest {
@Test
public void testOpenedDocumentShadowsPersistedFile() {
StringConcatenation _builder = new StringConcatenation();
_builder.append("type Test {");
_builder.newLine();
_builder.append(" ");
_builder.append("NonExisting foo");
_builder.newLine();
_builder.append("}");
_builder.newLine();
final String firstFile = this.writeFile("MyType1.testlang", _builder);
this.initialize();
this.assertEquals("Couldn\'t resolve reference to TypeDeclaration \'NonExisting\'.", IterableExtensions.<Diagnostic>head(this.getDiagnostics().get(firstFile)).getMessage());
StringConcatenation _builder_1 = new StringConcatenation();
_builder_1.append("type Foo {");
_builder_1.newLine();
_builder_1.append("}");
_builder_1.newLine();
final String path = this.writeFile("MyType2.testlang", _builder_1);
WorkspaceService _workspaceService = this.languageServer.getWorkspaceService();
FileEvent _fileEvent = new FileEvent(path, FileChangeType.Created);
DidChangeWatchedFilesParams _didChangeWatchedFilesParams = new DidChangeWatchedFilesParams(
Collections.<FileEvent>unmodifiableList(CollectionLiterals.<FileEvent>newArrayList(_fileEvent)));
_workspaceService.didChangeWatchedFiles(_didChangeWatchedFilesParams);
this.assertEquals("Couldn\'t resolve reference to TypeDeclaration \'NonExisting\'.", IterableExtensions.<Diagnostic>head(this.getDiagnostics().get(firstFile)).getMessage());
StringConcatenation _builder_2 = new StringConcatenation();
_builder_2.append("type NonExisting {");
_builder_2.newLine();
_builder_2.append("}");
_builder_2.newLine();
this.open(path, _builder_2.toString());
Assert.assertNull(IterableExtensions.<Diagnostic>head(this.getDiagnostics().get(firstFile)));
this.close(path);
this.assertEquals("Couldn\'t resolve reference to TypeDeclaration \'NonExisting\'.", IterableExtensions.<Diagnostic>head(this.getDiagnostics().get(firstFile)).getMessage());
}
@Test
public void testDidChange() {
StringConcatenation _builder = new StringConcatenation();
_builder.append("type Test {");
_builder.newLine();
_builder.append(" ");
_builder.append("NonExisting foo");
_builder.newLine();
_builder.append("}");
_builder.newLine();
final String firstFile = this.writeFile("MyType1.testlang", _builder);
this.initialize();
this.assertEquals("Couldn\'t resolve reference to TypeDeclaration \'NonExisting\'.", IterableExtensions.<Diagnostic>head(this.getDiagnostics().get(firstFile)).getMessage());
StringConcatenation _builder_1 = new StringConcatenation();
_builder_1.append("type Test {");
_builder_1.newLine();
_builder_1.append(" ");
_builder_1.append("NonExisting foo");
_builder_1.newLine();
_builder_1.append("}");
_builder_1.newLine();
this.open(firstFile, _builder_1.toString());
this.assertEquals("Couldn\'t resolve reference to TypeDeclaration \'NonExisting\'.", IterableExtensions.<Diagnostic>head(this.getDiagnostics().get(firstFile)).getMessage());
DidChangeTextDocumentParams _didChangeTextDocumentParams = new DidChangeTextDocumentParams();
final Procedure1<DidChangeTextDocumentParams> _function = (DidChangeTextDocumentParams it) -> {
VersionedTextDocumentIdentifier _versionedTextDocumentIdentifier = new VersionedTextDocumentIdentifier();
final Procedure1<VersionedTextDocumentIdentifier> _function_1 = (VersionedTextDocumentIdentifier it_1) -> {
it_1.setUri(firstFile);
it_1.setVersion(Integer.valueOf(2));
};
VersionedTextDocumentIdentifier _doubleArrow = ObjectExtensions.<VersionedTextDocumentIdentifier>operator_doubleArrow(_versionedTextDocumentIdentifier, _function_1);
it.setTextDocument(_doubleArrow);
TextDocumentContentChangeEvent _textDocumentContentChangeEvent = new TextDocumentContentChangeEvent();
final Procedure1<TextDocumentContentChangeEvent> _function_2 = (TextDocumentContentChangeEvent it_1) -> {
Position _position = new Position(1, 4);
Position _position_1 = new Position(1, 15);
Range _range = new Range(_position, _position_1);
it_1.setRange(_range);
it_1.setText("Test");
};
TextDocumentContentChangeEvent _doubleArrow_1 = ObjectExtensions.<TextDocumentContentChangeEvent>operator_doubleArrow(_textDocumentContentChangeEvent, _function_2);
it.setContentChanges(Collections.<TextDocumentContentChangeEvent>unmodifiableList(CollectionLiterals.<TextDocumentContentChangeEvent>newArrayList(_doubleArrow_1)));
};
DidChangeTextDocumentParams _doubleArrow = ObjectExtensions.<DidChangeTextDocumentParams>operator_doubleArrow(_didChangeTextDocumentParams, _function);
this.languageServer.didChange(_doubleArrow);
Assert.assertNull(IterableExtensions.<Diagnostic>head(this.getDiagnostics().get(firstFile)));
}
@Test
public void testDidClose() {
final String fileURI = this.writeFile("Foo.testlang", "");
this.initialize();
final String referencingFileURI = this.getVirtualFile("Bar.testlang");
StringConcatenation _builder = new StringConcatenation();
_builder.append("type Bar {");
_builder.newLine();
_builder.append(" ");
_builder.append("Foo foo");
_builder.newLine();
_builder.append("}");
_builder.newLine();
this.open(referencingFileURI, _builder.toString());
Assert.assertFalse(this.getDiagnostics().get(referencingFileURI).isEmpty());
this.open(fileURI, "type Foo {}");
Assert.assertTrue(this.getDiagnostics().get(referencingFileURI).isEmpty());
this.close(fileURI);
Assert.assertFalse(this.getDiagnostics().get(referencingFileURI).isEmpty());
}
@Test
public void testDidCloseInMemory() {
this.initialize();
final String fileURI = this.getVirtualFile("Foo.testlang");
this.open(fileURI, "type Foo {}");
final String referencingFileURI = this.getVirtualFile("Bar.testlang");
StringConcatenation _builder = new StringConcatenation();
_builder.append("type Bar {");
_builder.newLine();
_builder.append(" ");
_builder.append("Foo foo");
_builder.newLine();
_builder.append("}");
_builder.newLine();
this.open(referencingFileURI, _builder.toString());
Assert.assertTrue(this.getDiagnostics().get(referencingFileURI).isEmpty());
this.close(fileURI);
Assert.assertFalse(this.getDiagnostics().get(referencingFileURI).isEmpty());
}
@Test
public void testInMemory_GH_456() {
this.initialize();
final String uri = "inmemory:/foo/bar.testlang";
StringConcatenation _builder = new StringConcatenation();
_builder.append("type Foo { }");
_builder.newLine();
this.open(uri, _builder.toString());
StringConcatenation _builder_1 = new StringConcatenation();
_builder_1.append("Diagnostics could be empty but never null.");
Assert.assertNotNull(_builder_1.toString(), this.getDiagnostics().get(uri));
}
}

View file

@ -1,103 +0,0 @@
/**
* Copyright (c) 2016 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.ide.tests.server;
import java.util.Collections;
import org.eclipse.xtend2.lib.StringConcatenation;
import org.eclipse.xtext.ide.tests.server.AbstractTestLangLanguageServerTest;
import org.eclipse.xtext.testing.ReferenceTestConfiguration;
import org.eclipse.xtext.xbase.lib.CollectionLiterals;
import org.eclipse.xtext.xbase.lib.Pair;
import org.eclipse.xtext.xbase.lib.Procedures.Procedure1;
import org.junit.Test;
/**
* @author kosyakov - Initial contribution and API
*/
@SuppressWarnings("all")
public class ReferenceTest extends AbstractTestLangLanguageServerTest {
@Test
public void testReferences_01() {
final Procedure1<ReferenceTestConfiguration> _function = (ReferenceTestConfiguration it) -> {
StringConcatenation _builder = new StringConcatenation();
_builder.append("type Foo {}");
_builder.newLine();
_builder.append("type Bar {");
_builder.newLine();
_builder.append("\t");
_builder.append("Foo foo");
_builder.newLine();
_builder.append("}");
_builder.newLine();
it.setModel(_builder.toString());
it.setColumn("type F".length());
StringConcatenation _builder_1 = new StringConcatenation();
_builder_1.append("MyModel.testlang [[2, 1] .. [2, 4]]");
_builder_1.newLine();
it.setExpectedReferences(_builder_1.toString());
};
this.testReferences(_function);
}
@Test
public void testReferences_02() {
final Procedure1<ReferenceTestConfiguration> _function = (ReferenceTestConfiguration it) -> {
StringConcatenation _builder = new StringConcatenation();
_builder.append("type Foo {}");
_builder.newLine();
_builder.append("type Bar {");
_builder.newLine();
_builder.append("\t");
_builder.append("Foo foo");
_builder.newLine();
_builder.append("}");
_builder.newLine();
it.setModel(_builder.toString());
it.setColumn("type F".length());
it.setIncludeDeclaration(true);
StringConcatenation _builder_1 = new StringConcatenation();
_builder_1.append("MyModel.testlang [[0, 5] .. [0, 8]]");
_builder_1.newLine();
_builder_1.append("MyModel.testlang [[2, 1] .. [2, 4]]");
_builder_1.newLine();
it.setExpectedReferences(_builder_1.toString());
};
this.testReferences(_function);
}
@Test
public void testReferences_03_acrossFiles() {
final Procedure1<ReferenceTestConfiguration> _function = (ReferenceTestConfiguration it) -> {
StringConcatenation _builder = new StringConcatenation();
_builder.append("type Foo {}");
_builder.newLine();
Pair<String, String> _mappedTo = Pair.<String, String>of("foo.testlang", _builder.toString());
it.setFilesInScope(Collections.<String, CharSequence>unmodifiableMap(CollectionLiterals.<String, CharSequence>newHashMap(_mappedTo)));
StringConcatenation _builder_1 = new StringConcatenation();
_builder_1.append("type Bar {");
_builder_1.newLine();
_builder_1.append(" ");
_builder_1.append("Foo foo");
_builder_1.newLine();
_builder_1.append("}");
_builder_1.newLine();
it.setModel(_builder_1.toString());
it.setLine(1);
it.setColumn(6);
it.setIncludeDeclaration(true);
StringConcatenation _builder_2 = new StringConcatenation();
_builder_2.append("foo.testlang [[0, 5] .. [0, 8]]");
_builder_2.newLine();
_builder_2.append("MyModel.testlang [[1, 4] .. [1, 7]]");
_builder_2.newLine();
it.setExpectedReferences(_builder_2.toString());
};
this.testReferences(_function);
}
}

View file

@ -1,203 +0,0 @@
/**
* Copyright (c) 2016, 2017 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.ide.tests.server;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.ExecutionException;
import org.eclipse.lsp4j.DefinitionParams;
import org.eclipse.lsp4j.Diagnostic;
import org.eclipse.lsp4j.DidChangeWatchedFilesParams;
import org.eclipse.lsp4j.FileChangeType;
import org.eclipse.lsp4j.FileEvent;
import org.eclipse.lsp4j.TextDocumentIdentifier;
import org.eclipse.lsp4j.jsonrpc.ResponseErrorException;
import org.eclipse.lsp4j.jsonrpc.messages.ResponseErrorCode;
import org.eclipse.lsp4j.services.WorkspaceService;
import org.eclipse.xtend2.lib.StringConcatenation;
import org.eclipse.xtext.ide.tests.server.AbstractTestLangLanguageServerTest;
import org.eclipse.xtext.xbase.lib.CollectionLiterals;
import org.eclipse.xtext.xbase.lib.Exceptions;
import org.eclipse.xtext.xbase.lib.Functions.Function1;
import org.eclipse.xtext.xbase.lib.IterableExtensions;
import org.eclipse.xtext.xbase.lib.ObjectExtensions;
import org.eclipse.xtext.xbase.lib.Procedures.Procedure1;
import org.junit.Assert;
import org.junit.Test;
/**
* @author Sven Efftinge - Initial contribution and API
*/
@SuppressWarnings("all")
public class ServerTest extends AbstractTestLangLanguageServerTest {
@Test
public void testInitializeBuild() {
StringConcatenation _builder = new StringConcatenation();
_builder.append("type Test {");
_builder.newLine();
_builder.append(" ");
_builder.append("string foo");
_builder.newLine();
_builder.append("}");
_builder.newLine();
this.writeFile("MyType1.testlang", _builder);
this.initialize();
Assert.assertTrue(IterableExtensions.join(this.getDiagnostics().entrySet(), ","), IterableExtensions.<List<Diagnostic>>head(this.getDiagnostics().values()).isEmpty());
}
@Test
public void testInitializeBuildWithError() {
StringConcatenation _builder = new StringConcatenation();
_builder.append("type Test {");
_builder.newLine();
_builder.append(" ");
_builder.append("NonExisting foo");
_builder.newLine();
_builder.append("}");
_builder.newLine();
this.writeFile("MyType1.testlang", _builder);
this.initialize();
Diagnostic _head = IterableExtensions.<Diagnostic>head(IterableExtensions.<List<Diagnostic>>head(this.getDiagnostics().values()));
String _message = null;
if (_head!=null) {
_message=_head.getMessage();
}
this.assertEquals("Couldn\'t resolve reference to TypeDeclaration \'NonExisting\'.", _message);
Assert.assertEquals(1, IterableExtensions.<Diagnostic>head(IterableExtensions.<List<Diagnostic>>head(this.getDiagnostics().values())).getRange().getStart().getLine());
Assert.assertEquals(4, IterableExtensions.<Diagnostic>head(IterableExtensions.<List<Diagnostic>>head(this.getDiagnostics().values())).getRange().getStart().getCharacter());
Assert.assertEquals(1, IterableExtensions.<Diagnostic>head(IterableExtensions.<List<Diagnostic>>head(this.getDiagnostics().values())).getRange().getEnd().getLine());
Assert.assertEquals(15, IterableExtensions.<Diagnostic>head(IterableExtensions.<List<Diagnostic>>head(this.getDiagnostics().values())).getRange().getEnd().getCharacter());
}
@Test
public void testPublishDiagnosticsAfterInitialized() {
StringConcatenation _builder = new StringConcatenation();
_builder.append("type Test {");
_builder.newLine();
_builder.append(" ");
_builder.append("NonExisting foo");
_builder.newLine();
_builder.append("}");
_builder.newLine();
this.writeFile("MyType1.testlang", _builder);
this.initialize(null, false);
Assert.assertTrue("Diagnostics produced before \'initialized\' was called", this.getDiagnostics().isEmpty());
}
@Test
public void testIncrementalBuildWithError() {
StringConcatenation _builder = new StringConcatenation();
_builder.append("type Test {");
_builder.newLine();
_builder.append(" ");
_builder.append("NonExisting foo");
_builder.newLine();
_builder.append("}");
_builder.newLine();
this.writeFile("MyType1.testlang", _builder);
this.initialize();
this.assertEquals("Couldn\'t resolve reference to TypeDeclaration \'NonExisting\'.", IterableExtensions.<Diagnostic>head(IterableExtensions.<List<Diagnostic>>head(this.getDiagnostics().values())).getMessage());
StringConcatenation _builder_1 = new StringConcatenation();
_builder_1.append("type NonExisting {");
_builder_1.newLine();
_builder_1.append("}");
_builder_1.newLine();
final String path = this.writeFile("MyType2.testlang", _builder_1);
WorkspaceService _workspaceService = this.languageServer.getWorkspaceService();
FileEvent _fileEvent = new FileEvent(path, FileChangeType.Created);
DidChangeWatchedFilesParams _didChangeWatchedFilesParams = new DidChangeWatchedFilesParams(Collections.<FileEvent>unmodifiableList(CollectionLiterals.<FileEvent>newArrayList(_fileEvent)));
_workspaceService.didChangeWatchedFiles(_didChangeWatchedFilesParams);
Assert.assertNotNull(this.getDiagnostics().get(path));
final Function1<List<Diagnostic>, Boolean> _function = (List<Diagnostic> it) -> {
return Boolean.valueOf(it.isEmpty());
};
Assert.assertTrue(IterableExtensions.join(this.getDiagnostics().values(), ","), IterableExtensions.<List<Diagnostic>>forall(this.getDiagnostics().values(), _function));
}
@Test
public void testIncrementalDeletion() {
StringConcatenation _builder = new StringConcatenation();
_builder.append("type Test {");
_builder.newLine();
_builder.append(" ");
_builder.append("NonExisting foo");
_builder.newLine();
_builder.append("}");
_builder.newLine();
final String path = this.writeFile("MyType1.testlang", _builder);
this.initialize();
this.assertEquals("Couldn\'t resolve reference to TypeDeclaration \'NonExisting\'.",
IterableExtensions.<Diagnostic>head(IterableExtensions.<List<Diagnostic>>head(this.getDiagnostics().values())).getMessage());
this.deleteFile("MyType1.testlang");
WorkspaceService _workspaceService = this.languageServer.getWorkspaceService();
FileEvent _fileEvent = new FileEvent(path, FileChangeType.Deleted);
DidChangeWatchedFilesParams _didChangeWatchedFilesParams = new DidChangeWatchedFilesParams(Collections.<FileEvent>unmodifiableList(CollectionLiterals.<FileEvent>newArrayList(_fileEvent)));
_workspaceService.didChangeWatchedFiles(_didChangeWatchedFilesParams);
Assert.assertTrue(IterableExtensions.<List<Diagnostic>>head(this.getDiagnostics().values()).isEmpty());
}
@Test
public void testTwoFilesDeleteClose() {
final String fileURI = this.writeFile("Foo.testlang", "");
this.initialize();
final String referencingFileURI = this.getVirtualFile("Bar.testlang");
StringConcatenation _builder = new StringConcatenation();
_builder.append("type Bar {");
_builder.newLine();
_builder.append(" ");
_builder.append("Foo foo");
_builder.newLine();
_builder.append("}");
_builder.newLine();
this.open(referencingFileURI, _builder.toString());
Assert.assertFalse("Bar.testlang references missing type Foo from Foo.testlang: expect error",
this.getDiagnostics().get(referencingFileURI).isEmpty());
this.open(fileURI, "type Foo {}");
Assert.assertTrue("Bar.testlang references type Foo from Foo.testlang: expect no error",
this.getDiagnostics().get(referencingFileURI).isEmpty());
this.deleteFile(fileURI);
WorkspaceService _workspaceService = this.languageServer.getWorkspaceService();
FileEvent _fileEvent = new FileEvent(fileURI, FileChangeType.Deleted);
DidChangeWatchedFilesParams _didChangeWatchedFilesParams = new DidChangeWatchedFilesParams(Collections.<FileEvent>unmodifiableList(CollectionLiterals.<FileEvent>newArrayList(_fileEvent)));
_workspaceService.didChangeWatchedFiles(_didChangeWatchedFilesParams);
Assert.assertTrue("delete file on disk: expect no error", this.getDiagnostics().get(referencingFileURI).isEmpty());
this.close(fileURI);
Assert.assertFalse("close deleted file: expect error", this.getDiagnostics().get(referencingFileURI).isEmpty());
}
@Test
public void testMissingInitialize() {
try {
try {
DefinitionParams _definitionParams = new DefinitionParams();
final Procedure1<DefinitionParams> _function = (DefinitionParams it) -> {
TextDocumentIdentifier _textDocumentIdentifier = new TextDocumentIdentifier();
final Procedure1<TextDocumentIdentifier> _function_1 = (TextDocumentIdentifier it_1) -> {
it_1.setUri("file:/home/test/workspace/mydoc.testlang");
};
TextDocumentIdentifier _doubleArrow = ObjectExtensions.<TextDocumentIdentifier>operator_doubleArrow(_textDocumentIdentifier, _function_1);
it.setTextDocument(_doubleArrow);
};
DefinitionParams _doubleArrow = ObjectExtensions.<DefinitionParams>operator_doubleArrow(_definitionParams, _function);
this.languageServer.definition(_doubleArrow).get();
Assert.fail("Expected a ResponseErrorException");
} catch (final Throwable _t) {
if (_t instanceof ExecutionException) {
final ExecutionException exception = (ExecutionException)_t;
Throwable _cause = exception.getCause();
Assert.assertEquals(ResponseErrorCode.serverNotInitialized.getValue(), ((ResponseErrorException) _cause).getResponseError().getCode());
} else {
throw Exceptions.sneakyThrow(_t);
}
}
} catch (Throwable _e) {
throw Exceptions.sneakyThrow(_e);
}
}
}

View file

@ -1,171 +0,0 @@
/**
* Copyright (c) 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.ide.tests.server;
import com.google.inject.AbstractModule;
import com.google.inject.Inject;
import com.google.inject.Scopes;
import java.io.File;
import java.io.FileWriter;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import org.eclipse.lsp4j.DidChangeWorkspaceFoldersParams;
import org.eclipse.lsp4j.InitializeParams;
import org.eclipse.lsp4j.WorkspaceFolder;
import org.eclipse.lsp4j.WorkspaceFoldersChangeEvent;
import org.eclipse.xtend2.lib.StringConcatenation;
import org.eclipse.xtext.ide.server.ILanguageServerAccess;
import org.eclipse.xtext.ide.server.UriExtensions;
import org.eclipse.xtext.ide.server.WorkspaceManager;
import org.eclipse.xtext.ide.tests.server.AbstractTestLangLanguageServerTest;
import org.eclipse.xtext.resource.IResourceDescription;
import org.eclipse.xtext.util.Modules2;
import org.eclipse.xtext.xbase.lib.CollectionLiterals;
import org.eclipse.xtext.xbase.lib.Exceptions;
import org.eclipse.xtext.xbase.lib.Extension;
import org.eclipse.xtext.xbase.lib.ObjectExtensions;
import org.eclipse.xtext.xbase.lib.Procedures.Procedure0;
import org.eclipse.xtext.xbase.lib.Procedures.Procedure1;
import org.junit.Assert;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
/**
* @author Jan Koehnlein - Initial contribution and API
*/
@SuppressWarnings("all")
public class WorkspaceFoldersTest extends AbstractTestLangLanguageServerTest {
@Inject
@Extension
private UriExtensions _uriExtensions;
@Inject
private WorkspaceManager workspaceManager;
@Rule
public TemporaryFolder temporaryFolder = new TemporaryFolder();
@Test
public void testInitialize() {
try {
final File rootFolder1 = this.temporaryFolder.newFolder("root1");
final File rootFolder2 = this.temporaryFolder.newFolder("root2");
StringConcatenation _builder = new StringConcatenation();
_builder.append("type Foo {");
_builder.newLine();
_builder.append("\t");
_builder.append("Bar bar");
_builder.newLine();
_builder.append("}");
_builder.newLine();
this.writeFile(rootFolder1, "one.testlang", _builder);
StringConcatenation _builder_1 = new StringConcatenation();
_builder_1.append("type Bar {");
_builder_1.newLine();
_builder_1.append("\t");
_builder_1.append("Foo foo");
_builder_1.newLine();
_builder_1.append("}");
_builder_1.newLine();
final String twoUri = this.writeFile(rootFolder2, "two.testlang", _builder_1);
final Procedure1<InitializeParams> _function = (InitializeParams it) -> {
String _uriString = this._uriExtensions.toUriString(rootFolder1.toURI());
WorkspaceFolder _workspaceFolder = new WorkspaceFolder(_uriString, "root1");
String _uriString_1 = this._uriExtensions.toUriString(rootFolder2.toURI());
WorkspaceFolder _workspaceFolder_1 = new WorkspaceFolder(_uriString_1, "root2");
it.setWorkspaceFolders(Collections.<WorkspaceFolder>unmodifiableList(CollectionLiterals.<WorkspaceFolder>newArrayList(_workspaceFolder, _workspaceFolder_1)));
};
this.initialize(_function);
Assert.assertEquals(2, this.getDiagnostics().size());
Assert.assertEquals(1, this.getDiagnostics().get(twoUri).size());
final Procedure0 _function_1 = () -> {
DidChangeWorkspaceFoldersParams _didChangeWorkspaceFoldersParams = new DidChangeWorkspaceFoldersParams();
final Procedure1<DidChangeWorkspaceFoldersParams> _function_2 = (DidChangeWorkspaceFoldersParams it) -> {
WorkspaceFoldersChangeEvent _workspaceFoldersChangeEvent = new WorkspaceFoldersChangeEvent();
final Procedure1<WorkspaceFoldersChangeEvent> _function_3 = (WorkspaceFoldersChangeEvent it_1) -> {
String _uriString = this._uriExtensions.toUriString(rootFolder2.toURI());
WorkspaceFolder _workspaceFolder = new WorkspaceFolder(_uriString, "root2");
it_1.setRemoved(Collections.<WorkspaceFolder>unmodifiableList(CollectionLiterals.<WorkspaceFolder>newArrayList(_workspaceFolder)));
};
WorkspaceFoldersChangeEvent _doubleArrow = ObjectExtensions.<WorkspaceFoldersChangeEvent>operator_doubleArrow(_workspaceFoldersChangeEvent, _function_3);
it.setEvent(_doubleArrow);
};
DidChangeWorkspaceFoldersParams _doubleArrow = ObjectExtensions.<DidChangeWorkspaceFoldersParams>operator_doubleArrow(_didChangeWorkspaceFoldersParams, _function_2);
this.languageServer.didChangeWorkspaceFolders(_doubleArrow);
};
this.withBuild(_function_1);
Assert.assertEquals(0, this.getDiagnostics().get(twoUri).size());
final Procedure0 _function_2 = () -> {
DidChangeWorkspaceFoldersParams _didChangeWorkspaceFoldersParams = new DidChangeWorkspaceFoldersParams();
final Procedure1<DidChangeWorkspaceFoldersParams> _function_3 = (DidChangeWorkspaceFoldersParams it) -> {
WorkspaceFoldersChangeEvent _workspaceFoldersChangeEvent = new WorkspaceFoldersChangeEvent();
final Procedure1<WorkspaceFoldersChangeEvent> _function_4 = (WorkspaceFoldersChangeEvent it_1) -> {
String _uriString = this._uriExtensions.toUriString(rootFolder2.toURI());
WorkspaceFolder _workspaceFolder = new WorkspaceFolder(_uriString, "root2");
it_1.setAdded(Collections.<WorkspaceFolder>unmodifiableList(CollectionLiterals.<WorkspaceFolder>newArrayList(_workspaceFolder)));
};
WorkspaceFoldersChangeEvent _doubleArrow = ObjectExtensions.<WorkspaceFoldersChangeEvent>operator_doubleArrow(_workspaceFoldersChangeEvent, _function_4);
it.setEvent(_doubleArrow);
};
DidChangeWorkspaceFoldersParams _doubleArrow = ObjectExtensions.<DidChangeWorkspaceFoldersParams>operator_doubleArrow(_didChangeWorkspaceFoldersParams, _function_3);
this.languageServer.didChangeWorkspaceFolders(_doubleArrow);
};
this.withBuild(_function_2);
Assert.assertEquals(1, this.getDiagnostics().get(twoUri).size());
} catch (Throwable _e) {
throw Exceptions.sneakyThrow(_e);
}
}
protected void withBuild(final Procedure0 lambda) {
try {
final CompletableFuture<Void> future = new CompletableFuture<Void>();
final ILanguageServerAccess.IBuildListener _function = new ILanguageServerAccess.IBuildListener() {
@Override
public void afterBuild(final List<IResourceDescription.Delta> it) {
WorkspaceFoldersTest.this.workspaceManager.removeBuildListener(this);
future.complete(null);
}
};
this.workspaceManager.addBuildListener(_function);
lambda.apply();
future.get();
} catch (Throwable _e) {
throw Exceptions.sneakyThrow(_e);
}
}
public String writeFile(final File root, final String path, final CharSequence contents) {
try {
final File file = new File(root, path);
file.getParentFile().mkdirs();
file.createNewFile();
final FileWriter writer = new FileWriter(file);
writer.write(contents.toString());
writer.close();
return this._uriExtensions.toUriString(file.toURI().normalize());
} catch (Throwable _e) {
throw Exceptions.sneakyThrow(_e);
}
}
@Override
protected com.google.inject.Module getServerModule() {
final com.google.inject.Module defaultModule = super.getServerModule();
final com.google.inject.Module customModule = new AbstractModule() {
@Override
protected void configure() {
this.<WorkspaceManager>bind(WorkspaceManager.class).in(Scopes.SINGLETON);
}
};
return Modules2.mixin(defaultModule, customModule);
}
}

View file

@ -1,140 +0,0 @@
/**
* Copyright (c) 2016, 2017 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.ide.tests.server;
import com.google.inject.Guice;
import com.google.inject.Inject;
import com.google.inject.Injector;
import java.io.File;
import java.io.FileWriter;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import org.eclipse.emf.common.util.URI;
import org.eclipse.xtend2.lib.StringConcatenation;
import org.eclipse.xtext.ide.server.Document;
import org.eclipse.xtext.ide.server.ServerModule;
import org.eclipse.xtext.ide.server.UriExtensions;
import org.eclipse.xtext.ide.server.WorkspaceManager;
import org.eclipse.xtext.resource.XtextResource;
import org.eclipse.xtext.util.Files;
import org.eclipse.xtext.validation.Issue;
import org.eclipse.xtext.xbase.lib.CollectionLiterals;
import org.eclipse.xtext.xbase.lib.Exceptions;
import org.eclipse.xtext.xbase.lib.Extension;
import org.eclipse.xtext.xbase.lib.Functions.Function2;
import org.eclipse.xtext.xbase.lib.IterableExtensions;
import org.eclipse.xtext.xbase.lib.ObjectExtensions;
import org.eclipse.xtext.xbase.lib.Procedures.Procedure1;
import org.eclipse.xtext.xbase.lib.Procedures.Procedure2;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
/**
* @author Sven Efftinge - Initial contribution and API
*/
@SuppressWarnings("all")
public class WorkspaceManagerTest {
@Test
public void testDoRead() {
StringConcatenation _builder = new StringConcatenation();
_builder.append("type Test {");
_builder.newLine();
_builder.append(" ");
_builder.append("string foo");
_builder.newLine();
_builder.append("}");
_builder.newLine();
final URI path = this.operator_mappedTo("MyType1.testlang", _builder);
this.workspaceManger.doBuild(Collections.<URI>unmodifiableList(CollectionLiterals.<URI>newArrayList(path)), CollectionLiterals.<URI>emptyList(), null);
StringConcatenation _builder_1 = new StringConcatenation();
_builder_1.append("type Test {");
_builder_1.newLine();
_builder_1.append(" ");
_builder_1.append("Test foo");
_builder_1.newLine();
_builder_1.append("}");
_builder_1.newLine();
final String inMemContents = _builder_1.toString();
this.workspaceManger.didOpen(path, Integer.valueOf(1), inMemContents).build(null);
final Function2<Document, XtextResource, String> _function = (Document $0, XtextResource $1) -> {
return $0.getContents();
};
Assert.assertEquals(inMemContents, this.workspaceManger.<String>doRead(path, _function));
}
@Inject
protected WorkspaceManager workspaceManger;
@Inject
@Extension
protected UriExtensions uriExtensions;
@Before
public void setup() {
try {
ServerModule _serverModule = new ServerModule();
final Injector injector = Guice.createInjector(_serverModule);
injector.injectMembers(this);
File _file = new File("./test-data/test-project");
this.root = _file;
boolean _mkdirs = this.root.mkdirs();
boolean _not = (!_mkdirs);
if (_not) {
Files.cleanFolder(this.root, null, true, false);
}
this.root.deleteOnExit();
final Procedure2<URI, Iterable<Issue>> _function = (URI $0, Iterable<Issue> $1) -> {
this.diagnostics.put($0, IterableExtensions.<Issue>toList($1));
};
this.workspaceManger.initialize(this.uriExtensions.withEmptyAuthority(URI.createFileURI(this.root.getAbsolutePath())), _function, null);
} catch (Throwable _e) {
throw Exceptions.sneakyThrow(_e);
}
}
@After
public void cleanup() {
try {
boolean _exists = this.root.exists();
if (_exists) {
Files.cleanFolder(this.root, null, true, true);
}
} catch (Throwable _e) {
throw Exceptions.sneakyThrow(_e);
}
}
protected Map<URI, List<Issue>> diagnostics = CollectionLiterals.<URI, List<Issue>>newHashMap();
protected File root;
public URI operator_mappedTo(final String path, final CharSequence contents) {
try {
final File file = new File(this.root, path);
file.getParentFile().mkdirs();
file.createNewFile();
FileWriter _fileWriter = new FileWriter(file);
final Procedure1<FileWriter> _function = (FileWriter it) -> {
try {
it.write(contents.toString());
it.close();
} catch (Throwable _e) {
throw Exceptions.sneakyThrow(_e);
}
};
ObjectExtensions.<FileWriter>operator_doubleArrow(_fileWriter, _function);
return URI.createFileURI(file.getAbsolutePath());
} catch (Throwable _e) {
throw Exceptions.sneakyThrow(_e);
}
}
}

View file

@ -1,152 +0,0 @@
/**
* Copyright (c) 2018 TypeFox 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.ide.tests.testlanguage.editor.syntaxcoloring;
import com.google.common.base.Objects;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.function.Consumer;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.xtext.ide.editor.syntaxcoloring.DefaultSemanticHighlightingCalculator;
import org.eclipse.xtext.ide.editor.syntaxcoloring.IHighlightedPositionAcceptor;
import org.eclipse.xtext.ide.tests.testlanguage.testLanguage.Operation;
import org.eclipse.xtext.ide.tests.testlanguage.testLanguage.Parameter;
import org.eclipse.xtext.ide.tests.testlanguage.testLanguage.PrimitiveType;
import org.eclipse.xtext.ide.tests.testlanguage.testLanguage.Property;
import org.eclipse.xtext.ide.tests.testlanguage.testLanguage.TestLanguagePackage;
import org.eclipse.xtext.ide.tests.testlanguage.testLanguage.TypeDeclaration;
import org.eclipse.xtext.ide.tests.testlanguage.testLanguage.TypeReference;
import org.eclipse.xtext.nodemodel.ICompositeNode;
import org.eclipse.xtext.nodemodel.ILeafNode;
import org.eclipse.xtext.nodemodel.INode;
import org.eclipse.xtext.nodemodel.util.NodeModelUtils;
import org.eclipse.xtext.util.CancelIndicator;
import org.eclipse.xtext.xbase.lib.CollectionLiterals;
import org.eclipse.xtext.xbase.lib.Functions.Function1;
import org.eclipse.xtext.xbase.lib.IterableExtensions;
import org.eclipse.xtext.xbase.lib.ListExtensions;
@SuppressWarnings("all")
public class SemanticHighlightingCalculatorImpl extends DefaultSemanticHighlightingCalculator {
private static final String IDENTIFIER_STYLE = "identifier";
private static final String PRIMITIVE_TYPE_STYLE = "primitiveType";
private static final String TYPE_STYLE = "type";
private static final String TYPE_DECLARATION_STYLE = "typeDeclaration";
private static final String PARAMETER_NAME_STYLE = "parameterName";
private static final String OP_BODY_STYLE = "opBody";
public static final Set<String> STYLES = Collections.<String>unmodifiableSet(CollectionLiterals.<String>newHashSet(SemanticHighlightingCalculatorImpl.IDENTIFIER_STYLE, SemanticHighlightingCalculatorImpl.PRIMITIVE_TYPE_STYLE, SemanticHighlightingCalculatorImpl.TYPE_STYLE, SemanticHighlightingCalculatorImpl.TYPE_DECLARATION_STYLE, SemanticHighlightingCalculatorImpl.PARAMETER_NAME_STYLE, SemanticHighlightingCalculatorImpl.OP_BODY_STYLE));
@Override
protected boolean highlightElement(final EObject object, final IHighlightedPositionAcceptor acceptor, final CancelIndicator cancelIndicator) {
return this.doHighlightElement(object, acceptor);
}
protected boolean _doHighlightElement(final EObject it, final IHighlightedPositionAcceptor acceptor) {
return false;
}
protected boolean _doHighlightElement(final Property it, final IHighlightedPositionAcceptor acceptor) {
return this.doHighlightNode(acceptor, it, TestLanguagePackage.Literals.MEMBER__NAME, SemanticHighlightingCalculatorImpl.IDENTIFIER_STYLE);
}
protected boolean _doHighlightElement(final Operation it, final IHighlightedPositionAcceptor acceptor) {
final boolean canStop = this.doHighlightNode(acceptor, it, TestLanguagePackage.Literals.MEMBER__NAME, SemanticHighlightingCalculatorImpl.IDENTIFIER_STYLE);
final ICompositeNode opNode = NodeModelUtils.findActualNodeFor(it);
if ((opNode != null)) {
final Function1<ILeafNode, Boolean> _function = (ILeafNode it_1) -> {
boolean _isHidden = it_1.isHidden();
return Boolean.valueOf((!_isHidden));
};
final List<ILeafNode> inverseChildren = ListExtensions.<ILeafNode>reverse(IterableExtensions.<ILeafNode>toList(IterableExtensions.<ILeafNode>filter(opNode.getLeafNodes(), _function)));
int endOffset = (-1);
int startOffset = (-1);
ILeafNode _head = IterableExtensions.<ILeafNode>head(inverseChildren);
String _text = null;
if (_head!=null) {
_text=_head.getText();
}
boolean _equals = Objects.equal(_text, "}");
if (_equals) {
int _endOffset = IterableExtensions.<ILeafNode>head(inverseChildren).getEndOffset();
int _minus = (_endOffset - 1);
endOffset = _minus;
}
if ((endOffset != (-1))) {
final Function1<ILeafNode, Boolean> _function_1 = (ILeafNode it_1) -> {
String _trim = it_1.getText().trim();
return Boolean.valueOf(Objects.equal(_trim, "{"));
};
final ILeafNode opStartNode = IterableExtensions.<ILeafNode>findFirst(inverseChildren, _function_1);
if ((opStartNode != null)) {
int _offset = opStartNode.getOffset();
int _plus = (_offset + 1);
startOffset = _plus;
}
}
if (((startOffset >= 0) && (endOffset >= 0))) {
acceptor.addPosition(startOffset, (endOffset - startOffset), SemanticHighlightingCalculatorImpl.OP_BODY_STYLE);
}
}
return canStop;
}
protected boolean _doHighlightElement(final TypeDeclaration it, final IHighlightedPositionAcceptor acceptor) {
return this.doHighlightNode(acceptor, it, TestLanguagePackage.Literals.ABSTRACT_ELEMENT__NAME, SemanticHighlightingCalculatorImpl.TYPE_DECLARATION_STYLE);
}
protected boolean _doHighlightElement(final PrimitiveType it, final IHighlightedPositionAcceptor acceptor) {
return this.doHighlightNode(acceptor, it, TestLanguagePackage.Literals.PRIMITIVE_TYPE__NAME, SemanticHighlightingCalculatorImpl.PRIMITIVE_TYPE_STYLE);
}
protected boolean _doHighlightElement(final TypeReference it, final IHighlightedPositionAcceptor acceptor) {
return this.doHighlightNode(acceptor, it, TestLanguagePackage.Literals.TYPE_REFERENCE__TYPE_REF, SemanticHighlightingCalculatorImpl.TYPE_STYLE);
}
protected boolean _doHighlightElement(final Parameter it, final IHighlightedPositionAcceptor acceptor) {
return this.doHighlightNode(acceptor, it, TestLanguagePackage.Literals.PARAMETER__NAME, SemanticHighlightingCalculatorImpl.PARAMETER_NAME_STYLE);
}
public boolean doHighlightNode(final IHighlightedPositionAcceptor acceptor, final EObject object, final EStructuralFeature feature, final String style) {
final Consumer<INode> _function = (INode it) -> {
acceptor.addPosition(it.getOffset(), it.getLength(), style);
};
NodeModelUtils.findNodesForFeature(object, feature).forEach(_function);
return false;
}
public boolean doHighlightElement(final EObject it, final IHighlightedPositionAcceptor acceptor) {
if (it instanceof Operation) {
return _doHighlightElement((Operation)it, acceptor);
} else if (it instanceof PrimitiveType) {
return _doHighlightElement((PrimitiveType)it, acceptor);
} else if (it instanceof Property) {
return _doHighlightElement((Property)it, acceptor);
} else if (it instanceof TypeDeclaration) {
return _doHighlightElement((TypeDeclaration)it, acceptor);
} else if (it instanceof TypeReference) {
return _doHighlightElement((TypeReference)it, acceptor);
} else if (it instanceof Parameter) {
return _doHighlightElement((Parameter)it, acceptor);
} else if (it != null) {
return _doHighlightElement(it, acceptor);
} else {
throw new IllegalArgumentException("Unhandled parameter types: " +
Arrays.<Object>asList(it, acceptor).toString());
}
}
}

View file

@ -0,0 +1,84 @@
/**
* 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.xtext;
import java.util.List;
import org.eclipse.xtext.XtextStandaloneSetup;
import org.eclipse.xtext.resource.XtextResource;
import org.eclipse.xtext.tests.AbstractXtextTests;
import org.eclipse.xtext.util.CancelIndicator;
import org.eclipse.xtext.validation.CheckMode;
import org.eclipse.xtext.validation.Issue;
import org.junit.Assert;
import org.junit.Test;
import com.google.common.collect.Iterables;
/**
* @author efftinge - Initial contribution and API
*/
public class ReducedXtextResourceValidatorTest extends AbstractXtextTests {
@Override
public void setUp() throws Exception {
super.setUp();
with(new XtextStandaloneSetup());
resourceValidator = get(ReducedXtextResourceValidator.class);
}
private ReducedXtextResourceValidator resourceValidator;
@Test
public void testNoEcoreLinkingErrors() throws Exception {
String grammarAsString = "grammar test.Lang with org.eclipse.xtext.common.Terminals\n" +
"import 'http://test' as test\n" +
"Root returns test::Foo: name=ID;";
List<Issue> issues = resourceValidator.validate(getErroneousResource(grammarAsString),
CheckMode.NORMAL_AND_FAST, CancelIndicator.NullImpl);
Assert.assertEquals(issues.toString(), 0, issues.size());
}
@Test
public void testSyntaxErrors() throws Exception {
String grammarAsString = "grammar test.Lang with org.eclipse.xtext.common.Terminals\n" +
"import 'http://test' as test\n" +
"Root returns test::Foo: name=ID;;";
List<Issue> issues = resourceValidator.validate(getErroneousResource(grammarAsString),
CheckMode.NORMAL_AND_FAST, CancelIndicator.NullImpl);
Assert.assertEquals(issues.toString(), 1, issues.size());
Assert.assertTrue(issues.toString(),
Iterables.getFirst(issues, null).getMessage().contains("extraneous input ';'"));
}
@Test
public void testRuleLinkingErrors() throws Exception {
String grammarAsString = "grammar test.Lang with org.eclipse.xtext.common.Terminals\n" +
"import 'http://test' as test\n" +
"Root returns test::Foo : name=IDS;";
List<Issue> issues = resourceValidator.validate(getErroneousResource(grammarAsString),
CheckMode.NORMAL_AND_FAST, CancelIndicator.NullImpl);
Assert.assertEquals(issues.toString(), 1, issues.size());
Assert.assertTrue(issues.toString(), Iterables.getFirst(issues, null).getMessage().contains("IDS"));
}
@Test
public void testGrammarLinkingErrors() throws Exception {
String grammarAsString = "grammar test.Lang with org.eclipse.xtext.common.Trminals\n" +
"import 'http://test' as test\n" +
"Root returns test::Foo : name='foo';";
List<Issue> issues = resourceValidator.validate(getErroneousResource(grammarAsString),
CheckMode.NORMAL_AND_FAST, CancelIndicator.NullImpl);
Assert.assertEquals(issues.toString(), 1, issues.size());
Assert.assertTrue(issues.toString(), Iterables.getFirst(issues, null).getMessage().contains("Trminals"));
}
public XtextResource getErroneousResource(CharSequence seq) throws Exception {
return doGetResource(getAsStream(seq.toString()), getTestModelURI());
}
}

View file

@ -1,75 +0,0 @@
/*******************************************************************************
* Copyright (c) 2015 itemis AG (http://www.itemis.eu) and others.
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0.
*
* SPDX-License-Identifier: EPL-2.0
*******************************************************************************/
package org.eclipse.xtext.xtext
import org.eclipse.xtext.XtextStandaloneSetup
import org.eclipse.xtext.tests.AbstractXtextTests
import org.eclipse.xtext.util.CancelIndicator
import org.eclipse.xtext.validation.CheckMode
import org.junit.Test
/**
* @author efftinge - Initial contribution and API
*/
class ReducedXtextResourceValidatorTest extends AbstractXtextTests {
override void setUp() throws Exception {
super.setUp()
with(new XtextStandaloneSetup())
this.resourceValidator = get(ReducedXtextResourceValidator)
}
ReducedXtextResourceValidator resourceValidator
@Test def void testNoEcoreLinkingErrors() {
val grammarAsString = '''
grammar test.Lang with org.eclipse.xtext.common.Terminals
import 'http://test' as test
Root returns test::Foo: name=ID;
'''
val issues = resourceValidator.validate(grammarAsString.erroneousResource, CheckMode.NORMAL_AND_FAST, CancelIndicator.NullImpl)
assertEquals(issues.toString, 0, issues.size)
}
@Test def void testSyntaxErrors() {
val grammarAsString = '''
grammar test.Lang with org.eclipse.xtext.common.Terminals
import 'http://test' as test
Root returns test::Foo: name=ID;;
'''
val issues = resourceValidator.validate(grammarAsString.erroneousResource, CheckMode.NORMAL_AND_FAST, CancelIndicator.NullImpl)
assertEquals(issues.toString, 1, issues.size)
assertTrue(issues.toString, issues.head.message.contains("extraneous input ';'"))
}
@Test def void testRuleLinkingErrors() {
val grammarAsString = '''
grammar test.Lang with org.eclipse.xtext.common.Terminals
import 'http://test' as test
Root returns test::Foo : name=IDS;
'''
val issues = resourceValidator.validate(grammarAsString.erroneousResource, CheckMode.NORMAL_AND_FAST, CancelIndicator.NullImpl)
assertEquals(issues.toString, 1, issues.size)
assertTrue(issues.toString, issues.head.message.contains("IDS"))
}
@Test def void testGrammarLinkingErrors() {
val grammarAsString = '''
grammar test.Lang with org.eclipse.xtext.common.Trminals
import 'http://test' as test
Root returns test::Foo : name='foo';
'''
val issues = resourceValidator.validate(grammarAsString.erroneousResource, CheckMode.NORMAL_AND_FAST, CancelIndicator.NullImpl)
assertEquals(issues.toString, 1, issues.size)
assertTrue(issues.toString, issues.head.message.contains("Trminals"))
}
def getErroneousResource(CharSequence seq) {
return seq.toString.asStream.doGetResource(testModelURI)
}
}

View file

@ -0,0 +1,90 @@
/**
* Copyright (c) 2019, 2020 itemis AG (http://www.itemis.eu) and others.
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0.
*
* SPDX-License-Identifier: EPL-2.0
*/
package org.eclipse.xtext.xtext;
import org.eclipse.xtext.Grammar;
import org.eclipse.xtext.XtextPackage;
import org.eclipse.xtext.XtextStandaloneSetup;
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.AbstractXtextTests;
import org.eclipse.xtext.tests.XtextInjectorProvider;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import com.google.inject.Inject;
/**
* @author Eva Poell - Initial contribution and API
*/
@RunWith(XtextRunner.class)
@InjectWith(XtextInjectorProvider.class)
public class ValidationIssue1034Test extends AbstractXtextTests {
@Inject
private ParseHelper<Grammar> parseHelper;
@Inject
private ValidationTestHelper validationTestHelper;
@Before
@Override
public void setUp() throws Exception {
super.setUp();
with(XtextStandaloneSetup.class);
}
@Test
public void check_FirstRuleIsNotFragment() throws Exception {
String grammarAsString = "grammar com.space.Test with org.eclipse.xtext.common.Terminals\n" +
"generate testDSL 'http://space.com/test'\n" +
"Model:\n" +
" 'type' type=ID;";
validationTestHelper.assertNoIssues(parseHelper.parse(grammarAsString));
}
@Test
public void check_FirstRuleIsFragment() throws Exception {
String grammarAsString = "grammar com.space.Test with org.eclipse.xtext.common.Terminals\n" +
"generate testDSL 'http://space.com/test'\n" +
"fragment Model:\n" +
" 'type' type=ID;";
error(grammarAsString);
}
@Test
public void check_FirstRuleIsFragmentEmpty() throws Exception {
String grammarAsString = "grammar com.space.Test with org.eclipse.xtext.common.Terminals\n" +
"generate testDSL 'http://space.com/test'\n" +
"fragment Model:\n" +
" 'error'\n" +
"Greeting:\n" +
" 'Hello' name=ID '!';";
error(grammarAsString);
}
@Test
public void check_FirstRuleIsFragmentParams() throws Exception {
String grammarAsString = "grammar foo with org.eclipse.xtext.common.Terminals\n" +
"generate mm 'http://bar'\n" +
"fragment MyRule<MyParam>:\n" +
" <MyParam> name=ID\n" +
" | <!MyParam> name=STRING\n" +
" | name='name'\n" +
";";
error(grammarAsString);
}
private void error(CharSequence input) throws Exception {
validationTestHelper.assertError(parseHelper.parse(input), XtextPackage.Literals.PARSER_RULE,
XtextConfigurableIssueCodes.INVALID_FRAGMENT_AS_FIRST_RULE, "must not be a fragment");
}
}

View file

@ -1,83 +0,0 @@
/*******************************************************************************
* Copyright (c) 2019 itemis AG (http://www.itemis.eu) and others.
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0.
*
* SPDX-License-Identifier: EPL-2.0
*******************************************************************************/
package org.eclipse.xtext.xtext
import com.google.inject.Inject
import org.eclipse.xtext.Grammar
import org.eclipse.xtext.XtextStandaloneSetup
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.AbstractXtextTests
import org.eclipse.xtext.tests.XtextInjectorProvider
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import static org.eclipse.xtext.XtextPackage.Literals.PARSER_RULE
import static org.eclipse.xtext.xtext.XtextConfigurableIssueCodes.INVALID_FRAGMENT_AS_FIRST_RULE
/**
* @author Eva Poell - Initial contribution and API
*/
@RunWith(XtextRunner)
@InjectWith(XtextInjectorProvider)
class ValidationIssue1034Test extends AbstractXtextTests {
@Inject extension ParseHelper<Grammar>
@Inject extension ValidationTestHelper
@Before
override setUp() throws Exception {
super.setUp();
with(XtextStandaloneSetup)
}
@Test
def void check_FirstRuleIsNotFragment() {
'''grammar com.space.Test with org.eclipse.xtext.common.Terminals
generate testDSL "http://space.com/test"
Model:
"type" type=ID;'''.parse.assertNoIssues
}
@Test
def void check_FirstRuleIsFragment() {
'''grammar com.space.Test with org.eclipse.xtext.common.Terminals
generate testDSL "http://space.com/test"
fragment Model:
"type" type=ID;'''.error
}
@Test
def void check_FirstRuleIsFragmentEmpty() {
'''grammar com.space.Test with org.eclipse.xtext.common.Terminals
generate testDSL "http://space.com/test"
fragment Model:
"error"
Greeting:
'Hello' name=ID '!';'''.error
}
@Test
def void check_FirstRuleIsFragmentParams() {
'''grammar foo with org.eclipse.xtext.common.Terminals
generate mm "http://bar"
fragment MyRule<MyParam>:
<MyParam> name=ID
| <!MyParam> name=STRING
| name='name'
;'''.error
}
private def error(CharSequence input) {
input.parse.assertError(PARSER_RULE, INVALID_FRAGMENT_AS_FIRST_RULE, "must not be a fragment")
}
}

View file

@ -1,106 +0,0 @@
/**
* Copyright (c) 2015 itemis AG (http://www.itemis.eu) and others.
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0.
*
* SPDX-License-Identifier: EPL-2.0
*/
package org.eclipse.xtext.xtext;
import java.util.List;
import org.eclipse.xtend2.lib.StringConcatenation;
import org.eclipse.xtext.XtextStandaloneSetup;
import org.eclipse.xtext.resource.XtextResource;
import org.eclipse.xtext.tests.AbstractXtextTests;
import org.eclipse.xtext.util.CancelIndicator;
import org.eclipse.xtext.validation.CheckMode;
import org.eclipse.xtext.validation.Issue;
import org.eclipse.xtext.xbase.lib.Exceptions;
import org.eclipse.xtext.xbase.lib.IterableExtensions;
import org.eclipse.xtext.xtext.ReducedXtextResourceValidator;
import org.junit.Assert;
import org.junit.Test;
/**
* @author efftinge - Initial contribution and API
*/
@SuppressWarnings("all")
public class ReducedXtextResourceValidatorTest extends AbstractXtextTests {
@Override
public void setUp() throws Exception {
super.setUp();
XtextStandaloneSetup _xtextStandaloneSetup = new XtextStandaloneSetup();
this.with(_xtextStandaloneSetup);
this.resourceValidator = this.<ReducedXtextResourceValidator>get(ReducedXtextResourceValidator.class);
}
private ReducedXtextResourceValidator resourceValidator;
@Test
public void testNoEcoreLinkingErrors() {
StringConcatenation _builder = new StringConcatenation();
_builder.append("grammar test.Lang with org.eclipse.xtext.common.Terminals");
_builder.newLine();
_builder.append("import \'http://test\' as test");
_builder.newLine();
_builder.append("Root returns test::Foo: name=ID;");
_builder.newLine();
final String grammarAsString = _builder.toString();
final List<Issue> issues = this.resourceValidator.validate(this.getErroneousResource(grammarAsString), CheckMode.NORMAL_AND_FAST, CancelIndicator.NullImpl);
Assert.assertEquals(issues.toString(), 0, issues.size());
}
@Test
public void testSyntaxErrors() {
StringConcatenation _builder = new StringConcatenation();
_builder.append("grammar test.Lang with org.eclipse.xtext.common.Terminals");
_builder.newLine();
_builder.append("import \'http://test\' as test");
_builder.newLine();
_builder.append("Root returns test::Foo: name=ID;;");
_builder.newLine();
final String grammarAsString = _builder.toString();
final List<Issue> issues = this.resourceValidator.validate(this.getErroneousResource(grammarAsString), CheckMode.NORMAL_AND_FAST, CancelIndicator.NullImpl);
Assert.assertEquals(issues.toString(), 1, issues.size());
Assert.assertTrue(issues.toString(), IterableExtensions.<Issue>head(issues).getMessage().contains("extraneous input \';\'"));
}
@Test
public void testRuleLinkingErrors() {
StringConcatenation _builder = new StringConcatenation();
_builder.append("grammar test.Lang with org.eclipse.xtext.common.Terminals");
_builder.newLine();
_builder.append("import \'http://test\' as test");
_builder.newLine();
_builder.append("Root returns test::Foo : name=IDS;");
_builder.newLine();
final String grammarAsString = _builder.toString();
final List<Issue> issues = this.resourceValidator.validate(this.getErroneousResource(grammarAsString), CheckMode.NORMAL_AND_FAST, CancelIndicator.NullImpl);
Assert.assertEquals(issues.toString(), 1, issues.size());
Assert.assertTrue(issues.toString(), IterableExtensions.<Issue>head(issues).getMessage().contains("IDS"));
}
@Test
public void testGrammarLinkingErrors() {
StringConcatenation _builder = new StringConcatenation();
_builder.append("grammar test.Lang with org.eclipse.xtext.common.Trminals");
_builder.newLine();
_builder.append("import \'http://test\' as test");
_builder.newLine();
_builder.append("Root returns test::Foo : name=\'foo\';");
_builder.newLine();
final String grammarAsString = _builder.toString();
final List<Issue> issues = this.resourceValidator.validate(this.getErroneousResource(grammarAsString), CheckMode.NORMAL_AND_FAST, CancelIndicator.NullImpl);
Assert.assertEquals(issues.toString(), 1, issues.size());
Assert.assertTrue(issues.toString(), IterableExtensions.<Issue>head(issues).getMessage().contains("Trminals"));
}
public XtextResource getErroneousResource(final CharSequence seq) {
try {
return this.doGetResource(this.getAsStream(seq.toString()), this.getTestModelURI());
} catch (Throwable _e) {
throw Exceptions.sneakyThrow(_e);
}
}
}

View file

@ -1,141 +0,0 @@
/**
* Copyright (c) 2019 itemis AG (http://www.itemis.eu) and others.
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0.
*
* SPDX-License-Identifier: EPL-2.0
*/
package org.eclipse.xtext.xtext;
import com.google.inject.Inject;
import org.eclipse.xtend2.lib.StringConcatenation;
import org.eclipse.xtext.Grammar;
import org.eclipse.xtext.XtextPackage;
import org.eclipse.xtext.XtextStandaloneSetup;
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.AbstractXtextTests;
import org.eclipse.xtext.tests.XtextInjectorProvider;
import org.eclipse.xtext.xbase.lib.Exceptions;
import org.eclipse.xtext.xbase.lib.Extension;
import org.eclipse.xtext.xtext.XtextConfigurableIssueCodes;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
/**
* @author Eva Poell - Initial contribution and API
*/
@RunWith(XtextRunner.class)
@InjectWith(XtextInjectorProvider.class)
@SuppressWarnings("all")
public class ValidationIssue1034Test extends AbstractXtextTests {
@Inject
@Extension
private ParseHelper<Grammar> _parseHelper;
@Inject
@Extension
private ValidationTestHelper _validationTestHelper;
@Before
@Override
public void setUp() throws Exception {
super.setUp();
this.with(XtextStandaloneSetup.class);
}
@Test
public void check_FirstRuleIsNotFragment() {
try {
StringConcatenation _builder = new StringConcatenation();
_builder.append("grammar com.space.Test with org.eclipse.xtext.common.Terminals");
_builder.newLine();
_builder.append("\t\t");
_builder.append("generate testDSL \"http://space.com/test\"");
_builder.newLine();
_builder.append("\t\t");
_builder.append("Model:");
_builder.newLine();
_builder.append("\t\t\t");
_builder.append("\"type\" type=ID;");
this._validationTestHelper.assertNoIssues(this._parseHelper.parse(_builder));
} catch (Throwable _e) {
throw Exceptions.sneakyThrow(_e);
}
}
@Test
public void check_FirstRuleIsFragment() {
StringConcatenation _builder = new StringConcatenation();
_builder.append("grammar com.space.Test with org.eclipse.xtext.common.Terminals");
_builder.newLine();
_builder.append("\t\t");
_builder.append("generate testDSL \"http://space.com/test\"");
_builder.newLine();
_builder.append("\t\t");
_builder.append("fragment Model:");
_builder.newLine();
_builder.append("\t\t\t");
_builder.append("\"type\" type=ID;");
this.error(_builder);
}
@Test
public void check_FirstRuleIsFragmentEmpty() {
StringConcatenation _builder = new StringConcatenation();
_builder.append("grammar com.space.Test with org.eclipse.xtext.common.Terminals");
_builder.newLine();
_builder.append("\t\t");
_builder.append("generate testDSL \"http://space.com/test\"");
_builder.newLine();
_builder.append("\t\t");
_builder.append("fragment Model:");
_builder.newLine();
_builder.append("\t\t\t");
_builder.append("\"error\"");
_builder.newLine();
_builder.append("\t\t");
_builder.append("Greeting:");
_builder.newLine();
_builder.append("\t\t\t");
_builder.append("\'Hello\' name=ID \'!\';");
this.error(_builder);
}
@Test
public void check_FirstRuleIsFragmentParams() {
StringConcatenation _builder = new StringConcatenation();
_builder.append("grammar foo with org.eclipse.xtext.common.Terminals");
_builder.newLine();
_builder.append("\t\t");
_builder.append("generate mm \"http://bar\"");
_builder.newLine();
_builder.append("\t\t");
_builder.append("fragment MyRule<MyParam>:");
_builder.newLine();
_builder.append("\t\t ");
_builder.append("<MyParam> name=ID");
_builder.newLine();
_builder.append("\t\t ");
_builder.append("| <!MyParam> name=STRING");
_builder.newLine();
_builder.append("\t\t ");
_builder.append("| name=\'name\'");
_builder.newLine();
_builder.append("\t\t");
_builder.append(";");
this.error(_builder);
}
private void error(final CharSequence input) {
try {
this._validationTestHelper.assertError(this._parseHelper.parse(input), XtextPackage.Literals.PARSER_RULE, XtextConfigurableIssueCodes.INVALID_FRAGMENT_AS_FIRST_RULE, "must not be a fragment");
} catch (Throwable _e) {
throw Exceptions.sneakyThrow(_e);
}
}
}

View file

@ -0,0 +1,379 @@
/**
* 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.xtext.generator;
import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import org.apache.log4j.Logger;
import org.eclipse.emf.common.util.Diagnostic;
import org.eclipse.emf.common.util.DiagnosticChain;
import org.eclipse.emf.common.util.TreeIterator;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.emf.ecore.EValidator;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.xtext.AbstractMetamodelDeclaration;
import org.eclipse.xtext.Grammar;
import org.eclipse.xtext.GrammarUtil;
import org.eclipse.xtext.ReferencedMetamodel;
import org.eclipse.xtext.XtextPackage;
import org.eclipse.xtext.nodemodel.INode;
import org.eclipse.xtext.nodemodel.util.NodeModelUtils;
import org.eclipse.xtext.resource.IResourceDescription;
import org.eclipse.xtext.resource.IResourceServiceProvider;
import org.eclipse.xtext.resource.XtextResource;
import org.eclipse.xtext.resource.impl.ResourceDescriptionsData;
import org.eclipse.xtext.xtext.RuleNames;
import org.eclipse.xtext.xtext.generator.model.GuiceModuleAccess;
import org.eclipse.xtext.xtext.generator.model.StandaloneSetupAccess;
import org.eclipse.xtext.xtext.generator.model.project.IXtextProjectConfig;
import com.google.common.base.Joiner;
import com.google.common.collect.Lists;
import com.google.inject.Binder;
import com.google.inject.Inject;
import com.google.inject.Injector;
import com.google.inject.Provider;
/**
* Configuration for an Xtext language. Use this class if you need to specify
* exactly which generator fragments you want to include, or alternatively
* {@link StandardLanguage} to work with the standard fragments.
*
* <p>
* The most important property is {@code name}, which should be set to the
* language name exactly as specified in the grammar file. If the default
* grammar resolution based on the name does not work in your particular
* scenario, set the {@code grammarUri} property instead. Furthermore, use
* {@code fileExtensions} to specify the file extensions for your language.
* </p>
*
* <p>
* Generator fragments can be added with the {@code fragment} property. See
* {@link StandardLanguage} for a list of useful fragments.
* </p>
*
* @noextend This class should not be extended by clients.
*/
public class XtextGeneratorLanguage extends CompositeGeneratorFragment2 implements IXtextGeneratorLanguage {
private static final Logger LOG = Logger.getLogger(XtextGeneratorLanguage.class);
private String grammarUri;
private String name;
private Boolean generateXtendStubs;
private Grammar grammar;
private RuleNames ruleNames;
private List<String> fileExtensions;
private List<String> referencedResources = new ArrayList<>();
private ResourceSet resourceSet;
private com.google.inject.Module guiceModule = (Binder it) -> {
};
private final StandaloneSetupAccess runtimeGenSetup = new StandaloneSetupAccess();
private final GuiceModuleAccess runtimeGenModule = new GuiceModuleAccess();
private final GuiceModuleAccess ideGenModule = new GuiceModuleAccess();
private final GuiceModuleAccess eclipsePluginGenModule = new GuiceModuleAccess();
private final GuiceModuleAccess webGenModule = new GuiceModuleAccess();
@Inject
private Provider<ResourceSet> resourceSetProvider;
@Inject
private IXtextProjectConfig projectConfig;
@Inject
private CodeConfig codeConfig;
@Inject
private XtextGeneratorResourceSetInitializer resourceSetInitializer;
/**
* The URI of the grammar file. Use this property if the automatic grammar
* resolution based on {@link #setName(String)} does not work in your
* particular scenario.
*/
public void setGrammarUri(String uri) {
this.grammarUri = uri;
}
public String getGrammarUri() {
if (grammarUri != null) {
return grammarUri;
} else {
return new File(projectConfig.getRuntime().getSrc().getPath(), name.replace(".", "/") + ".xtext").toURI()
.toString();
}
}
/**
* The language name exactly as specified in the grammar.
*/
public void setName(String name) {
this.name = name;
}
/**
* Either a single file extension or a comma-separated list of extensions
* for which the language shall be registered.
*/
public void setFileExtensions(String fileExtensions) {
this.fileExtensions = Arrays.asList(fileExtensions.trim().split("\\s*,\\s*"));
}
/**
* Add a resource to be included in the resource set that will be used to
* load the grammar file. This is often necessary if additional Ecore models
* are referenced by the grammar.
*/
public void addReferencedResource(String referencedResource) {
referencedResources.add(referencedResource);
}
@Override
public List<String> getFileExtensions() {
if (fileExtensions == null || fileExtensions.isEmpty()) {
setFileExtensions(GrammarUtil.getSimpleName(grammar).toLowerCase());
LOG.info("No explicit fileExtensions configured. Using '*." + fileExtensions + "'.");
}
return fileExtensions;
}
/**
* @deprecated Use {@link CodeConfig#setPreferXtendStubs(boolean)} instead
*/
@Deprecated
public void setGenerateXtendStubs(Boolean generateXtendStubs) {
this.generateXtendStubs = generateXtendStubs;
}
/**
* @deprecated Use {@link CodeConfig#isPreferXtendStubs()} instead
*/
@Deprecated
@Override
public boolean isGenerateXtendStubs() {
if (generateXtendStubs != null) {
return generateXtendStubs.booleanValue();
} else {
return codeConfig.isPreferXtendStubs();
}
}
@Override
public void initialize(Injector injector) {
getFragments().addAll(0, getImplicitFragments());
injector.injectMembers(this);
if (resourceSet == null) {
resourceSet = resourceSetProvider.get();
}
resourceSetInitializer.initialize(resourceSet, referencedResources);
if (!resourceSet.getResources().isEmpty()) {
installIndex();
int i = 0;
int size = resourceSet.getResources().size();
while (i < size) {
Resource res = resourceSet.getResources().get(i);
if (res.getContents().isEmpty()) {
LOG.error("Error loading '" + res.getURI() + "'");
} else {
if (!res.getErrors().isEmpty()) {
LOG.error("Error loading '" + res.getURI() + "':\n" + Joiner.on("\n").join(res.getErrors()));
}
}
i++;
}
EcoreUtil.resolveAll(resourceSet);
}
if (getGrammarUri() == null) {
throw new IllegalStateException("No grammarUri or language name given");
}
XtextResource resource = (XtextResource) resourceSet.getResource(URI.createURI(getGrammarUri()), true);
if (resource.getContents().isEmpty()) {
throw new IllegalArgumentException("Couldn't load grammar for '" + getGrammarUri() + "'.");
}
if (!resource.getErrors().isEmpty()) {
LOG.error(resource.getErrors());
throw new IllegalStateException(
"Problem parsing '" + getGrammarUri() + "':\n" + Joiner.on("\n").join(resource.getErrors()));
}
Grammar grammar = (Grammar) resource.getContents().get(0);
validateGrammar(grammar);
initialize(grammar);
super.initialize(injector);
}
protected List<? extends IXtextGeneratorFragment> getImplicitFragments() {
List<ImplicitFragment> fragments = new ArrayList<>();
fragments.add(new ImplicitFragment());
return fragments;
}
public void initialize(Grammar grammar) {
this.grammar = grammar;
this.ruleNames = RuleNames.getRuleNames(grammar, true);
}
private void installIndex() {
ResourceDescriptionsData index = new ResourceDescriptionsData(Collections.emptyList());
List<Resource> resources = Lists.newArrayList(resourceSet.getResources());
for (Resource resource : resources) {
index(resource, resource.getURI(), index);
}
ResourceDescriptionsData.ResourceSetAdapter.installResourceDescriptionsData(resourceSet, index);
}
private void index(Resource resource, URI uri, ResourceDescriptionsData index) {
IResourceServiceProvider serviceProvider = IResourceServiceProvider.Registry.INSTANCE
.getResourceServiceProvider(uri);
if (serviceProvider != null) {
IResourceDescription resourceDescription = serviceProvider.getResourceDescriptionManager()
.getResourceDescription(resource);
if (resourceDescription != null) {
index.addDescription(uri, resourceDescription);
}
}
}
protected void validateGrammar(Grammar grammar) {
validateAllImports(grammar);
EValidator validator = EValidator.Registry.INSTANCE.getEValidator(XtextPackage.eINSTANCE);
if (validator != null) {
DiagnosticChain chain = new DiagnosticChain() {
@Override
public void add(Diagnostic diagnostic) {
if (diagnostic.getSeverity() == Diagnostic.ERROR) {
String grammarName = "Validation Error in " + grammar.getName() + ": ";
if (diagnostic.getException() == null) {
throw new IllegalStateException(grammarName + diagnostic.getMessage());
} else {
throw new IllegalStateException(grammarName + diagnostic.getMessage(),
diagnostic.getException());
}
}
}
@Override
public void addAll(Diagnostic diagnostic) {
add(diagnostic);
}
@Override
public void merge(Diagnostic diagnostic) {
throw new UnsupportedOperationException();
}
};
validator.validate(grammar, chain, null);
TreeIterator<EObject> iterator = grammar.eAllContents();
while (iterator.hasNext()) {
validator.validate(iterator.next(), chain, new HashMap<Object, Object>());
}
}
}
protected void validateAllImports(Grammar grammar) {
for (AbstractMetamodelDeclaration amd : GrammarUtil.allMetamodelDeclarations(grammar)) {
if (amd instanceof ReferencedMetamodel) {
validateReferencedMetamodel(((ReferencedMetamodel) amd));
}
}
}
protected void validateReferencedMetamodel(ReferencedMetamodel ref) {
if (ref.getEPackage() != null && !ref.getEPackage().eIsProxy()) {
return;
}
EReference eref = XtextPackage.Literals.ABSTRACT_METAMODEL_DECLARATION__EPACKAGE;
List<INode> nodes = NodeModelUtils.findNodesForFeature(ref, eref);
String refName = null;
if (nodes.isEmpty()) {
refName = "(unknown)";
} else {
refName = NodeModelUtils.getTokenText(nodes.get(0));
}
String grammarName = GrammarUtil.getGrammar(ref).getName();
String msg = "The EPackage " + refName + " in grammar " + grammarName + " could not be found. "
+ "You might want to register that EPackage in your workflow file.";
throw new IllegalStateException(msg);
}
@Override
public Grammar getGrammar() {
return grammar;
}
public RuleNames getRuleNames() {
return ruleNames;
}
public List<String> getReferencedResources() {
return referencedResources;
}
@Override
public ResourceSet getResourceSet() {
return resourceSet;
}
public void setResourceSet(ResourceSet resourceSet) {
this.resourceSet = resourceSet;
}
public com.google.inject.Module getGuiceModule() {
return guiceModule;
}
public void setGuiceModule(com.google.inject.Module guiceModule) {
this.guiceModule = guiceModule;
}
@Override
public StandaloneSetupAccess getRuntimeGenSetup() {
return runtimeGenSetup;
}
@Override
public GuiceModuleAccess getRuntimeGenModule() {
return runtimeGenModule;
}
@Override
public GuiceModuleAccess getIdeGenModule() {
return ideGenModule;
}
@Override
public GuiceModuleAccess getEclipsePluginGenModule() {
return eclipsePluginGenModule;
}
@Override
public GuiceModuleAccess getWebGenModule() {
return webGenModule;
}
}

View file

@ -1,285 +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.xtext.generator
import com.google.common.base.Joiner
import com.google.common.collect.Lists
import com.google.inject.Inject
import com.google.inject.Injector
import com.google.inject.Module
import com.google.inject.Provider
import java.io.File
import java.util.Collections
import java.util.HashMap
import java.util.List
import org.apache.log4j.Logger
import org.eclipse.emf.common.util.Diagnostic
import org.eclipse.emf.common.util.DiagnosticChain
import org.eclipse.emf.common.util.URI
import org.eclipse.emf.ecore.EValidator
import org.eclipse.emf.ecore.resource.Resource
import org.eclipse.emf.ecore.resource.ResourceSet
import org.eclipse.emf.ecore.util.EcoreUtil
import org.eclipse.xtend.lib.annotations.Accessors
import org.eclipse.xtext.Grammar
import org.eclipse.xtext.GrammarUtil
import org.eclipse.xtext.ReferencedMetamodel
import org.eclipse.xtext.XtextPackage
import org.eclipse.xtext.nodemodel.util.NodeModelUtils
import org.eclipse.xtext.resource.IResourceServiceProvider
import org.eclipse.xtext.resource.XtextResource
import org.eclipse.xtext.resource.impl.ResourceDescriptionsData
import org.eclipse.xtext.xtext.RuleNames
import org.eclipse.xtext.xtext.generator.model.GuiceModuleAccess
import org.eclipse.xtext.xtext.generator.model.StandaloneSetupAccess
import org.eclipse.xtext.xtext.generator.model.project.IXtextProjectConfig
/**
* Configuration for an Xtext language. Use this class if you need to specify exactly which generator
* fragments you want to include, or alternatively {@link StandardLanguage} to work with the standard
* fragments.
*
* <p>The most important property is {@code name}, which should be set to the language name exactly
* as specified in the grammar file. If the default grammar resolution based on the name does not
* work in your particular scenario, set the {@code grammarUri} property instead. Furthermore,
* use {@code fileExtensions} to specify the file extensions for your language.</p>
*
* <p>Generator fragments can be added with the {@code fragment} property. See {@link StandardLanguage}
* for a list of useful fragments.</p>
*
* @noextend This class should not be extended by clients.
*/
class XtextGeneratorLanguage extends CompositeGeneratorFragment2 implements IXtextGeneratorLanguage {
static val Logger LOG = Logger.getLogger(XtextGeneratorLanguage)
String grammarUri
String name
Boolean generateXtendStubs
@Accessors(PUBLIC_GETTER)
Grammar grammar
@Accessors(PUBLIC_GETTER)
RuleNames ruleNames
@Accessors(PUBLIC_GETTER)
List<String> fileExtensions
@Accessors(PUBLIC_GETTER)
List<String> referencedResources = newArrayList()
@Accessors
ResourceSet resourceSet
@Accessors
Module guiceModule = []
@Accessors
val runtimeGenSetup = new StandaloneSetupAccess
@Accessors
val runtimeGenModule = new GuiceModuleAccess
@Accessors
val ideGenModule = new GuiceModuleAccess
@Accessors
val eclipsePluginGenModule = new GuiceModuleAccess
@Accessors
val webGenModule = new GuiceModuleAccess
@Inject Provider<ResourceSet> resourceSetProvider
@Inject IXtextProjectConfig projectConfig
@Inject CodeConfig codeConfig
@Inject XtextGeneratorResourceSetInitializer resourceSetInitializer
/**
* The URI of the grammar file. Use this property if the automatic grammar resolution based on {@link #setName(String)}
* does not work in your particular scenario.
*/
def void setGrammarUri(String uri) {
this.grammarUri = uri
}
def String getGrammarUri() {
grammarUri ?: new File(projectConfig.runtime.src.path, name.replace('.', '/') + ".xtext").toURI.toString
}
/**
* The language name exactly as specified in the grammar.
*/
def void setName(String name) {
this.name = name
}
/**
* Either a single file extension or a comma-separated list of extensions for which the language
* shall be registered.
*/
def void setFileExtensions(String fileExtensions) {
this.fileExtensions = fileExtensions.trim.split('\\s*,\\s*').toList
}
/**
* Add a resource to be included in the resource set that will be used to load the grammar file.
* This is often necessary if additional Ecore models are referenced by the grammar.
*/
def void addReferencedResource(String referencedResource) {
this.referencedResources += referencedResource
}
override getFileExtensions() {
if (fileExtensions === null || fileExtensions.empty) {
fileExtensions = GrammarUtil.getSimpleName(grammar).toLowerCase
LOG.info("No explicit fileExtensions configured. Using '*." + fileExtensions + "'.")
}
return fileExtensions
}
/**
* @deprecated Use {@link CodeConfig#setPreferXtendStubs(boolean)} instead
*/
@Deprecated
def void setGenerateXtendStubs(Boolean generateXtendStubs) {
this.generateXtendStubs = generateXtendStubs
}
/**
* @deprecated Use {@link CodeConfig#isPreferXtendStubs()} instead
*/
@Deprecated
override isGenerateXtendStubs() {
if (generateXtendStubs !== null) generateXtendStubs.booleanValue else codeConfig.preferXtendStubs
}
override initialize(Injector injector) {
fragments.addAll(0, implicitFragments)
injector.injectMembers(this)
if (resourceSet === null)
resourceSet = resourceSetProvider.get()
resourceSetInitializer.initialize(resourceSet, referencedResources)
if (!resourceSet.resources.isEmpty) {
installIndex()
for (var i = 0, var size = resourceSet.resources.size; i < size; i++) {
val res = resourceSet.resources.get(i)
if (res.getContents().isEmpty())
XtextGeneratorLanguage.LOG.error("Error loading '" + res.getURI() + "'")
else if (!res.getErrors().isEmpty())
XtextGeneratorLanguage.LOG.error("Error loading '" + res.getURI() + "':\n" + Joiner.on('\n').join(res.getErrors()))
}
EcoreUtil.resolveAll(resourceSet)
}
if (getGrammarUri === null) {
throw new IllegalStateException("No grammarUri or language name given")
}
val resource = resourceSet.getResource(URI.createURI(getGrammarUri), true) as XtextResource
if (resource.contents.isEmpty) {
throw new IllegalArgumentException("Couldn't load grammar for '" + getGrammarUri + "'.")
}
if (!resource.errors.isEmpty) {
XtextGeneratorLanguage.LOG.error(resource.errors)
throw new IllegalStateException("Problem parsing '" + getGrammarUri + "':\n" + Joiner.on('\n').join(resource.getErrors()))
}
val grammar = resource.contents.get(0) as Grammar
validateGrammar(grammar)
initialize(grammar)
super.initialize(injector)
}
protected def List<? extends IXtextGeneratorFragment> getImplicitFragments() {
val fragments = newArrayList
fragments += new ImplicitFragment
return fragments
}
def void initialize(Grammar grammar) {
this.grammar = grammar
this.ruleNames = RuleNames.getRuleNames(grammar, true)
}
private def void installIndex() {
val index = new ResourceDescriptionsData(Collections.emptyList)
val resources = Lists.newArrayList(resourceSet.resources)
for (resource : resources) {
index(resource, resource.URI, index)
}
ResourceDescriptionsData.ResourceSetAdapter.installResourceDescriptionsData(resourceSet, index)
}
private def void index(Resource resource, URI uri, ResourceDescriptionsData index) {
val serviceProvider = IResourceServiceProvider.Registry.INSTANCE.getResourceServiceProvider(uri)
if (serviceProvider !== null) {
val resourceDescription = serviceProvider.resourceDescriptionManager.getResourceDescription(resource)
if (resourceDescription !== null) {
index.addDescription(uri, resourceDescription)
}
}
}
protected def void validateGrammar(Grammar grammar) {
validateAllImports(grammar)
val validator = EValidator.Registry.INSTANCE.getEValidator(XtextPackage.eINSTANCE)
if (validator !== null) {
val chain = new DiagnosticChain() {
override add(Diagnostic diagnostic) {
if (diagnostic.severity == Diagnostic.ERROR) {
val grammarName = "Validation Error in " + grammar.name + ": "
if (diagnostic.exception === null)
throw new IllegalStateException(grammarName + diagnostic.message)
else
throw new IllegalStateException(grammarName + diagnostic.message, diagnostic.exception)
}
}
override addAll(Diagnostic diagnostic) {
add(diagnostic)
}
override merge(Diagnostic diagnostic) {
throw new UnsupportedOperationException
}
}
validator.validate(grammar, chain, null)
val iterator = grammar.eAllContents
while (iterator.hasNext) {
validator.validate(iterator.next, chain, new HashMap);
}
}
}
protected def void validateAllImports(Grammar grammar) {
for (amd : GrammarUtil.allMetamodelDeclarations(grammar)) {
if (amd instanceof ReferencedMetamodel)
validateReferencedMetamodel(amd)
}
}
protected def void validateReferencedMetamodel(ReferencedMetamodel ref) {
if (ref.EPackage !== null && !ref.EPackage.eIsProxy) {
return
}
val eref = XtextPackage.Literals.ABSTRACT_METAMODEL_DECLARATION__EPACKAGE
val nodes = NodeModelUtils.findNodesForFeature(ref, eref)
val refName = if (nodes.empty) '(unknown)' else NodeModelUtils.getTokenText(nodes.get(0))
val grammarName = GrammarUtil.getGrammar(ref).name
val msg = "The EPackage " + refName + " in grammar " + grammarName + " could not be found. "
+ "You might want to register that EPackage in your workflow file."
throw new IllegalStateException(msg)
}
}

View file

@ -0,0 +1,223 @@
/**
* 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.xtext.generator.model.project;
import org.eclipse.emf.mwe2.runtime.Mandatory;
import org.eclipse.xtext.xtext.generator.Issues;
import com.google.common.base.Objects;
/**
* Specialized project configuration that uses standard names and paths. Usually
* it is sufficient to set the {@code baseName} and {@code rootPath} properties
* and to enable the required subprojects.
*
* @noextend This class should not be extended by clients.
*/
public class StandardProjectConfig extends XtextProjectConfig {
/**
* set to {@code true} by the project wizard(s) in case "Maven/Gradle"
* source layout is selected.
*/
private boolean mavenLayout;
private boolean createEclipseMetaData;
private String rootPath;
private String baseName;
/**
* The base name of the project, which is usually equal to the runtime
* subproject.
*/
@Mandatory
public String setBaseName(String baseName) {
return this.baseName = baseName;
}
/**
* The root path, usually {@code ".."}.
*/
@Mandatory
public String setRootPath(String rootPath) {
return this.rootPath = rootPath;
}
@Override
public void checkConfiguration(Issues issues) {
super.checkConfiguration(issues);
if (rootPath == null) {
issues.addError("The property 'rootPath' must be set", this);
}
if (baseName == null) {
issues.addError("The property 'baseName' must be set", this);
}
}
@Override
public void setDefaults() {
super.setDefaults();
for(SubProjectConfig it : getEnabledProjects()) {
if (it.getName() == null) {
it.setName(computeName(it));
}
if (it.getRootPath() == null) {
it.setRoot(computeRoot(it));
}
if (it.getMetaInfPath() == null) {
it.setMetaInf(computeMetaInf(it));
}
if (it.getSrcPath() == null) {
it.setSrc(computeSrc(it));
}
if (it.getSrcGenPath() == null) {
it.setSrcGen(computeSrcGen(it));
}
if (it.getIconsPath() == null) {
it.setIcons(computeIcons(it));
}
if (it instanceof BundleProjectConfig) {
if (createEclipseMetaData) {
BundleProjectConfig bundleProjectConfig = (BundleProjectConfig) it;
if (bundleProjectConfig.getManifest() == null) {
bundleProjectConfig.setManifest(newManifestAccess());
}
if (bundleProjectConfig.getPluginXml() == null) {
bundleProjectConfig.setPluginXml(newPluginXmlAccess());
}
}
}
if (it instanceof RuntimeProjectConfig) {
RuntimeProjectConfig runtimeProjectConfig = (RuntimeProjectConfig) it;
if (!(runtimeProjectConfig.getEcoreModelPath() != null)) {
runtimeProjectConfig.setEcoreModel(computeEcoreModel(runtimeProjectConfig));
}
}
if (it instanceof WebProjectConfig) {
WebProjectConfig webProjectConfig = (WebProjectConfig) it;
if (webProjectConfig.getAssetsPath() == null) {
webProjectConfig.setAssets(computeAssets(webProjectConfig));
}
}
};
}
protected String computeName(SubProjectConfig project) {
if (Objects.equal(project, getRuntime())) {
return baseName;
} else if (Objects.equal(project, getRuntimeTest())) {
if (!mavenLayout) {
return baseName + ".tests";
} else {
return baseName;
}
} else if (Objects.equal(project, getGenericIde())) {
return baseName + ".ide";
} else if (Objects.equal(project, getEclipsePlugin())) {
return baseName + ".ui";
} else if (Objects.equal(project, getEclipsePluginTest())) {
if (!mavenLayout) {
return baseName + ".ui.tests";
} else {
return baseName + ".ui";
}
} else if (Objects.equal(project, getWeb())) {
return baseName + ".web";
}
return null;
}
protected String computeRoot(SubProjectConfig project) {
return rootPath + "/"+ project.getName();
}
/**
* In case of "Maven/Gradle" source layout the src outlet is named
* 'src/main/java', test classes go into 'src/test/java' instead of any
* dedicated '...tests' project.
*/
protected String computeSrc(SubProjectConfig project) {
if (mavenLayout) {
return project.getRootPath() + "/" + "src/"+ computeSourceSet(project) + "/java";
} else {
return project.getRootPath() + "/" + "src";
}
}
/**
* In case of "Maven/Gradle" source layout the srcGen outlet is named
* 'src/main/xtext-gen', test-related srcGen classes go into
* 'src/test/xtext-gen' instead of any dedicated '...tests' project. Don't
* confuse it with 'src/main/xtend-gen'!
*/
protected String computeSrcGen(SubProjectConfig project) {
if (mavenLayout) {
return project.getRootPath() + "/" + "src/"+ computeSourceSet(project) + "/xtext-gen";
} else {
return project.getRootPath() + "/" + "src-gen";
}
}
protected String computeMetaInf(SubProjectConfig project) {
if (mavenLayout) {
return project.getRootPath() + "/" + "src/"+ computeSourceSet(project) + "/resources/META-INF";
} else {
return project.getRootPath() + "/" + "META-INF";
}
}
protected String computeEcoreModel(RuntimeProjectConfig project) {
return project.getRootPath() + "/" + "model/generated";
}
protected String computeAssets(WebProjectConfig project) {
if (mavenLayout) {
return project.getRootPath() + "/" + "src/"+ computeSourceSet(project) + "/webapp";
} else {
return project.getRootPath() + "/" + "WebRoot";
}
}
protected String computeSourceSet(SubProjectConfig project) {
if (getTestProjects().contains(project)) {
return "test";
} else {
return "main";
}
}
protected String computeIcons(SubProjectConfig project) {
return project.getRootPath() + "/" + "icons";
}
public boolean isMavenLayout() {
return mavenLayout;
}
public void setMavenLayout(boolean mavenLayout) {
this.mavenLayout = mavenLayout;
}
public boolean isCreateEclipseMetaData() {
return createEclipseMetaData;
}
public void setCreateEclipseMetaData(boolean createEclipseMetaData) {
this.createEclipseMetaData = createEclipseMetaData;
}
public String getRootPath() {
return rootPath;
}
public String getBaseName() {
return baseName;
}
}

View file

@ -1,141 +0,0 @@
/*******************************************************************************
* Copyright (c) 2015, 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.xtext.generator.model.project
import org.eclipse.emf.mwe2.runtime.Mandatory
import org.eclipse.xtend.lib.annotations.Accessors
import org.eclipse.xtext.xtext.generator.Issues
/**
* Specialized project configuration that uses standard names and paths. Usually it is sufficient to
* set the {@code baseName} and {@code rootPath} properties and to enable the required subprojects.
*
* @noextend This class should not be extended by clients.
*/
@Accessors
class StandardProjectConfig extends XtextProjectConfig {
/** set to {@code true} by the project wizard(s) in case "Maven/Gradle" source layout is selected. */
boolean mavenLayout
boolean createEclipseMetaData
String rootPath
String baseName
/**
* The base name of the project, which is usually equal to the runtime subproject.
*/
@Mandatory
def setBaseName(String baseName) {
this.baseName = baseName
}
/**
* The root path, usually {@code ".."}.
*/
@Mandatory
def setRootPath(String rootPath) {
this.rootPath = rootPath
}
override checkConfiguration(Issues issues) {
super.checkConfiguration(issues)
if (rootPath === null)
issues.addError("The property 'rootPath' must be set", this)
if (baseName === null)
issues.addError("The property 'baseName' must be set", this)
}
override setDefaults() {
super.setDefaults
enabledProjects.forEach [
if (name === null)
name = computeName
if (it.rootPath === null)
root = computeRoot
if (metaInfPath === null)
metaInf = computeMetaInf
if (srcPath === null)
src = computeSrc
if (srcGenPath === null)
srcGen = computeSrcGen
if (iconsPath === null)
icons = computeIcons
if (it instanceof BundleProjectConfig) {
if (createEclipseMetaData) {
if (manifest === null)
manifest = newManifestAccess
if (pluginXml === null)
pluginXml = newPluginXmlAccess
}
}
if (it instanceof RuntimeProjectConfig) {
if (ecoreModelPath === null)
ecoreModel = computeEcoreModel
}
if (it instanceof WebProjectConfig) {
if (assetsPath === null)
assets = computeAssets
}
]
}
protected def computeName(SubProjectConfig project) {
switch project {
case runtime: baseName
case runtimeTest: if (!mavenLayout) baseName + '.tests' else baseName
case genericIde: baseName + '.ide'
case eclipsePlugin: baseName + '.ui'
case eclipsePluginTest: if (!mavenLayout) baseName + '.ui.tests' else baseName + '.ui'
case web: baseName + '.web'
}
}
protected def computeRoot(SubProjectConfig project) {
rootPath + '/' + project.name
}
/**
* In case of "Maven/Gradle" source layout the src outlet is named 'src/main/java',
* test classes go into 'src/test/java' instead of any dedicated '...tests' project.
*/
protected def computeSrc(SubProjectConfig project) {
project.rootPath + '/' + if(mavenLayout) 'src/' + project.computeSourceSet + '/java' else 'src'
}
/**
* In case of "Maven/Gradle" source layout the srcGen outlet is named 'src/main/xtext-gen',
* test-related srcGen classes go into 'src/test/xtext-gen' instead of any dedicated '...tests' project.
* Don't confuse it with 'src/main/xtend-gen'!
*/
protected def computeSrcGen(SubProjectConfig project) {
project.rootPath + '/' + if(mavenLayout) 'src/' + project.computeSourceSet + '/xtext-gen' else 'src-gen'
}
protected def computeMetaInf(SubProjectConfig project) {
project.rootPath + '/' + if(mavenLayout) 'src/' + project.computeSourceSet + '/resources/META-INF' else 'META-INF'
}
protected def computeEcoreModel(RuntimeProjectConfig project) {
project.rootPath + '/' + 'model/generated'
}
protected def computeAssets(WebProjectConfig project) {
project.rootPath + '/' + if(mavenLayout) 'src/' + project.computeSourceSet + '/webapp' else 'WebRoot'
}
protected def computeSourceSet(SubProjectConfig project) {
if(testProjects.contains(project)) 'test' else 'main'
}
protected def computeIcons(SubProjectConfig project) {
project.rootPath + '/' + 'icons'
}
}

View file

@ -0,0 +1,314 @@
/**
* 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.xtext.generator.parser.antlr;
import java.io.CharArrayWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.eclipse.xtext.AbstractRule;
import org.eclipse.xtext.Grammar;
import org.eclipse.xtext.GrammarUtil;
import org.eclipse.xtext.ParserRule;
import org.eclipse.xtext.UnorderedGroup;
import org.eclipse.xtext.generator.LineSeparatorHarmonizer;
import org.eclipse.xtext.util.Strings;
import org.eclipse.xtext.xtext.generator.AbstractXtextGeneratorFragment;
import org.eclipse.xtext.xtext.generator.CodeConfig;
import org.eclipse.xtext.xtext.generator.Issues;
import org.eclipse.xtext.xtext.generator.model.IXtextGeneratorFileSystemAccess;
import org.eclipse.xtext.xtext.generator.model.TypeReference;
import org.eclipse.xtext.xtext.generator.parser.antlr.postProcessing.SuppressWarningsProcessor;
import org.eclipse.xtext.xtext.generator.parser.antlr.splitting.AntlrCodeQualityHelper;
import org.eclipse.xtext.xtext.generator.parser.antlr.splitting.AntlrLexerSplitter;
import org.eclipse.xtext.xtext.generator.parser.antlr.splitting.AntlrParserSplitter;
import org.eclipse.xtext.xtext.generator.parser.antlr.splitting.BacktrackingGuardForUnorderedGroupsRemover;
import org.eclipse.xtext.xtext.generator.parser.antlr.splitting.BacktrackingGuardRemover;
import org.eclipse.xtext.xtext.generator.parser.antlr.splitting.PartialClassExtractor;
import org.eclipse.xtext.xtext.generator.parser.antlr.splitting.SyntacticPredicateFixup;
import org.eclipse.xtext.xtext.generator.parser.antlr.splitting.UnorderedGroupsSplitter;
import com.google.common.collect.Iterators;
import com.google.common.collect.Lists;
import com.google.inject.Inject;
public abstract class AbstractAntlrGeneratorFragment2 extends AbstractXtextGeneratorFragment {
@Inject
private AntlrToolFacade antlrTool;
@Inject
private AntlrCodeQualityHelper codeQualityHelper;
@Inject
private LineSeparatorHarmonizer newLineNormalizer;
@Inject
private CodeConfig codeConfig;
private AntlrOptions options = new AntlrOptions();
private ArrayList<String> antlrParams = new ArrayList<>();
public void addAntlrParam(String param) {
antlrParams.add(param);
}
public String[] getAntlrParams() {
ArrayList<String> params = Lists.newArrayList(antlrParams);
// setting the default conversion timeout to 100secs.
// There seem to be no practical situations where the NFA conversion
// would hang,
// so Terence suggested here [1] to remove the option all together
// [1] -
// http://antlr.1301665.n2.nabble.com/Xconversiontimeout-td5294411.html
if (!params.contains("-Xconversiontimeout")) {
params.add(0, "-Xconversiontimeout");
params.add(1, "100000");
}
return params.toArray(new String[0]);
}
@Override
public void checkConfiguration(Issues issues) {
super.checkConfiguration(issues);
if (!antlrTool.isWorkable()) {
issues.addError(
"\n\n*ATTENTION*\nIt is highly recommended to use ANTLR's parser generator (get it from 'http://xtext.itemis.com/'). \nAs an alternative to ANTLR you could also use the alternative implementation shipped with Xtext.\nTo do so use the generator fragment 'org.eclipse.xtext.generator.parser.packrat.PackratParserFragment' in your mwe2 file instead.");
}
}
@Override
public void generate() {
checkGrammar();
doGenerate();
}
protected abstract void doGenerate();
protected void checkGrammar() {
if (!hasProductionRules(getGrammar())) {
throw new IllegalArgumentException(
"You may not generate an ANTLR parser for a grammar without production rules.");
}
}
protected boolean hasProductionRules(Grammar grammar) {
AbstractRule firstRule = grammar.getRules().get(0);
return firstRule instanceof ParserRule && !GrammarUtil.isDatatypeRule((ParserRule) firstRule);
}
protected void splitLexerClassFile(IXtextGeneratorFileSystemAccess fsa, TypeReference lexer) {
String content = fsa.readTextFile(lexer.getJavaPath()).toString();
AntlrLexerSplitter splitter = new AntlrLexerSplitter(content);
splitter.setCasesPerSpecialStateSwitch(options.getCasesPerSpecialStateSwitch());
fsa.generateFile(lexer.getJavaPath(), splitter.transform());
}
protected void splitParserClassFile(IXtextGeneratorFileSystemAccess fsa, TypeReference parser) {
String content = fsa.readTextFile(parser.getJavaPath()).toString();
AntlrParserSplitter splitter = new AntlrParserSplitter(content, getOptions().getFieldsPerClass());
PartialClassExtractor extractor = new PartialClassExtractor(splitter.transform(), getOptions().getMethodsPerClass());
fsa.generateFile(parser.getJavaPath(), extractor.transform());
}
protected void simplifyUnorderedGroupPredicatesIfRequired(Grammar grammar, IXtextGeneratorFileSystemAccess fsa,
TypeReference parser) {
if (containsUnorderedGroup(grammar) || hasParameterizedRules(grammar)) {
simplifyUnorderedGroupPredicates(fsa, parser);
}
}
protected boolean hasParameterizedRules(Grammar grammar) {
for (ParserRule rule : GrammarUtil.allParserRules(grammar)) {
if (!rule.getParameters().isEmpty()) {
return true;
}
}
return false;
}
protected void simplifyUnorderedGroupPredicates(IXtextGeneratorFileSystemAccess fsa, TypeReference parser) {
String content = fsa.readTextFile(parser.getJavaPath()).toString();
UnorderedGroupsSplitter splitter = new UnorderedGroupsSplitter(content);
String transformed = splitter.transform();
SyntacticPredicateFixup fixup = new SyntacticPredicateFixup(transformed);
transformed = fixup.transform();
BacktrackingGuardForUnorderedGroupsRemover remover = new BacktrackingGuardForUnorderedGroupsRemover(
transformed);
String newContent = remover.transform();
fsa.generateFile(parser.getJavaPath(), newContent);
}
protected void suppressWarnings(IXtextGeneratorFileSystemAccess fsa, TypeReference type) {
String content = fsa.readTextFile(type.getJavaPath()).toString();
String newContent = new SuppressWarningsProcessor().process(content);
fsa.generateFile(type.getJavaPath(), newContent);
}
protected void suppressWarnings(IXtextGeneratorFileSystemAccess fsa, TypeReference... types) {
if (types != null) {
for (TypeReference it : types) {
suppressWarnings(fsa, it);
}
}
}
protected void normalizeLineDelimiters(IXtextGeneratorFileSystemAccess fsa, TypeReference type) {
String content = fsa.readTextFile(type.getJavaPath()).toString();
content = newLineNormalizer.postProcess(fsa.getURI(type.getJavaPath()), content).toString();
content = content.replaceAll("\"\\+(\\r)?\\n\\s+\"", "");
fsa.generateFile(type.getJavaPath(), content);
}
protected void normalizeLineDelimiters(IXtextGeneratorFileSystemAccess fsa, TypeReference... types) {
if (types != null) {
for (TypeReference it : types) {
normalizeLineDelimiters(fsa, it);
}
}
}
protected void normalizeTokens(IXtextGeneratorFileSystemAccess fsa, String tokenFile) {
String content = fsa.readTextFile(tokenFile).toString();
content = newLineNormalizer.postProcess(fsa.getURI(tokenFile), content).toString();
List<String> splitted = Strings.split(content, codeConfig.getLineDelimiter());
Collections.sort(splitted);
content = Strings.concat(codeConfig.getLineDelimiter(), splitted) + codeConfig.getLineDelimiter();
fsa.generateFile(tokenFile, content);
}
protected void splitParserAndLexerIfEnabled(IXtextGeneratorFileSystemAccess fsa, TypeReference parser,
TypeReference lexer) {
improveCodeQuality(fsa, lexer, parser);
if (getOptions().isClassSplitting()) {
splitLexerClassFile(fsa, lexer);
splitParserClassFile(fsa, parser);
}
}
protected void improveCodeQuality(IXtextGeneratorFileSystemAccess fsa, TypeReference lexer, TypeReference parser) {
improveLexerCodeQuality(fsa, lexer);
improveParserCodeQuality(fsa, parser);
}
protected void improveParserCodeQuality(IXtextGeneratorFileSystemAccess fsa, TypeReference parser) {
String parserContent = fsa.readTextFile(parser.getJavaPath()).toString();
parserContent = codeQualityHelper.stripUnnecessaryComments(parserContent, options);
parserContent = codeQualityHelper.removeDuplicateBitsets(parserContent, options);
parserContent = codeQualityHelper.removeDuplicateDFAs(parserContent, options);
fsa.generateFile(parser.getJavaPath(), parserContent);
}
protected void improveLexerCodeQuality(IXtextGeneratorFileSystemAccess fsa, TypeReference lexer) {
String lexerContent = fsa.readTextFile(lexer.getJavaPath()).toString();
lexerContent = codeQualityHelper.stripUnnecessaryComments(lexerContent, options);
fsa.generateFile(lexer.getJavaPath(), lexerContent);
}
protected void cleanupLexerTokensFile(AntlrGrammar lexerGrammar, KeywordHelper helper,
IXtextGeneratorFileSystemAccess fsa) {
try {
if (options.isBacktrackLexer()) {
MutableTokenDefProvider provider = createLexerTokensProvider(lexerGrammar, helper, fsa);
Iterator<Map.Entry<Integer, String>> entries = provider.getTokenDefMap().entrySet().iterator();
while (entries.hasNext()) {
String value = entries.next().getValue();
if (!helper.isKeywordRule(value) && !value.startsWith("RULE_") && !value.startsWith("SUPER_")) {
entries.remove();
}
}
CharArrayWriter writer = new CharArrayWriter();
provider.writeTokenFile(new PrintWriter(writer));
fsa.generateFile(lexerGrammar.getTokensFileName(), new String(writer.toCharArray()));
}
} catch (IOException e) {
throw new RuntimeException(e);
}
}
protected MutableTokenDefProvider createLexerTokensProvider(AntlrGrammar lexerGrammar, KeywordHelper helper,
IXtextGeneratorFileSystemAccess fsa) {
MutableTokenDefProvider provider = new MutableTokenDefProvider(helper,
Charset.forName(codeConfig.getEncoding()));
provider.setAntlrTokenFileProvider(() -> {
return fsa.readBinaryFile(lexerGrammar.getTokensFileName());
});
return provider;
}
protected void cleanupParserTokensFile(AntlrGrammar lexerGrammar, AntlrGrammar parserGrammar, KeywordHelper helper,
IXtextGeneratorFileSystemAccess fsa) {
try {
MutableTokenDefProvider provider = createLexerTokensProvider(lexerGrammar, helper, fsa);
for (Map.Entry<Integer, String> entry : provider.getTokenDefMap().entrySet()) {
String value = entry.getValue();
if (helper.isKeywordRule(value)) {
String keywordAsAntlrString = AntlrGrammarGenUtil.toAntlrString(helper.getKeywordValue(value));
entry.setValue("'" + keywordAsAntlrString + "'");
} else {
if (value.startsWith("'")) {
entry.setValue("'" + AntlrGrammarGenUtil.toAntlrString(value) + "'");
}
}
}
CharArrayWriter writer = new CharArrayWriter();
provider.writeTokenFile(new PrintWriter(writer));
fsa.generateFile(parserGrammar.getTokensFileName(), new String(writer.toCharArray()));
} catch (IOException e) {
throw new RuntimeException(e);
}
}
protected void removeBackTrackingGuards(IXtextGeneratorFileSystemAccess fsa, TypeReference parser,
int lookaheadThreshold) {
String content = fsa.readTextFile(parser.getJavaPath()).toString();
BacktrackingGuardRemover remover = new BacktrackingGuardRemover(content, lookaheadThreshold);
String newContent = remover.transform();
fsa.generateFile(parser.getJavaPath(), newContent);
}
protected boolean containsUnorderedGroup(Grammar grammar) {
for (ParserRule rule : GrammarUtil.allParserRules(grammar)) {
if (Iterators.filter(rule.eAllContents(), UnorderedGroup.class).hasNext()) {
return true;
}
}
return false;
}
protected AntlrToolFacade getAntlrTool() {
return antlrTool;
}
protected AntlrCodeQualityHelper getCodeQualityHelper() {
return codeQualityHelper;
}
protected LineSeparatorHarmonizer getNewLineNormalizer() {
return newLineNormalizer;
}
protected CodeConfig getCodeConfig() {
return codeConfig;
}
public AntlrOptions getOptions() {
return options;
}
public void setOptions(AntlrOptions options) {
this.options = options;
}
}

View file

@ -1,244 +0,0 @@
/*******************************************************************************
* Copyright (c) 2015 itemis AG (http://www.itemis.eu) and others.
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0.
*
* SPDX-License-Identifier: EPL-2.0
*******************************************************************************/
package org.eclipse.xtext.xtext.generator.parser.antlr
import com.google.common.collect.Iterators
import com.google.common.collect.Lists
import com.google.inject.Inject
import java.io.CharArrayWriter
import java.io.PrintWriter
import java.nio.charset.Charset
import java.util.Collections
import org.eclipse.xtend.lib.annotations.Accessors
import org.eclipse.xtext.AbstractRule
import org.eclipse.xtext.Grammar
import org.eclipse.xtext.GrammarUtil
import org.eclipse.xtext.ParserRule
import org.eclipse.xtext.UnorderedGroup
import org.eclipse.xtext.generator.LineSeparatorHarmonizer
import org.eclipse.xtext.util.Strings
import org.eclipse.xtext.xtext.generator.AbstractXtextGeneratorFragment
import org.eclipse.xtext.xtext.generator.CodeConfig
import org.eclipse.xtext.xtext.generator.Issues
import org.eclipse.xtext.xtext.generator.model.IXtextGeneratorFileSystemAccess
import org.eclipse.xtext.xtext.generator.model.TypeReference
import org.eclipse.xtext.xtext.generator.parser.antlr.postProcessing.SuppressWarningsProcessor
import org.eclipse.xtext.xtext.generator.parser.antlr.splitting.AntlrCodeQualityHelper
import org.eclipse.xtext.xtext.generator.parser.antlr.splitting.AntlrLexerSplitter
import org.eclipse.xtext.xtext.generator.parser.antlr.splitting.AntlrParserSplitter
import org.eclipse.xtext.xtext.generator.parser.antlr.splitting.BacktrackingGuardForUnorderedGroupsRemover
import org.eclipse.xtext.xtext.generator.parser.antlr.splitting.BacktrackingGuardRemover
import org.eclipse.xtext.xtext.generator.parser.antlr.splitting.PartialClassExtractor
import org.eclipse.xtext.xtext.generator.parser.antlr.splitting.SyntacticPredicateFixup
import org.eclipse.xtext.xtext.generator.parser.antlr.splitting.UnorderedGroupsSplitter
abstract class AbstractAntlrGeneratorFragment2 extends AbstractXtextGeneratorFragment {
@Inject @Accessors(PROTECTED_GETTER) AntlrToolFacade antlrTool
@Inject @Accessors(PROTECTED_GETTER) AntlrCodeQualityHelper codeQualityHelper
@Inject @Accessors(PROTECTED_GETTER) LineSeparatorHarmonizer newLineNormalizer
@Inject @Accessors(PROTECTED_GETTER) CodeConfig codeConfig
@Accessors AntlrOptions options = new AntlrOptions
val antlrParams = <String>newArrayList
def void addAntlrParam(String param) {
antlrParams.add(param)
}
def String[] getAntlrParams() {
var params = Lists.newArrayList(antlrParams)
// setting the default conversion timeout to 100secs.
// There seem to be no practical situations where the NFA conversion would hang,
// so Terence suggested here [1] to remove the option all together
// [1] - http://antlr.1301665.n2.nabble.com/Xconversiontimeout-td5294411.html
if (!params.contains("-Xconversiontimeout")) {
params.add(0, "-Xconversiontimeout")
params.add(1, "100000")
}
return params
}
override void checkConfiguration(Issues issues) {
super.checkConfiguration(issues)
if (!antlrTool.isWorkable) {
issues.addError("\n\n*ATTENTION*\nIt is highly recommended to use ANTLR's parser generator (get it from 'http://xtext.itemis.com/'). \nAs an alternative to ANTLR you could also use the alternative implementation shipped with Xtext.\nTo do so use the generator fragment 'org.eclipse.xtext.generator.parser.packrat.PackratParserFragment' in your mwe2 file instead.")
}
}
override void generate() {
checkGrammar()
doGenerate()
}
def protected abstract void doGenerate()
def protected void checkGrammar() {
if(!hasProductionRules(getGrammar()))
throw new IllegalArgumentException("You may not generate an ANTLR parser for a grammar without production rules.")
}
def protected boolean hasProductionRules(Grammar grammar) {
var AbstractRule firstRule = grammar.getRules().get(0)
return firstRule instanceof ParserRule && !GrammarUtil::isDatatypeRule(firstRule as ParserRule)
}
def protected void splitLexerClassFile(IXtextGeneratorFileSystemAccess fsa, TypeReference lexer) {
val content = fsa.readTextFile(lexer.javaPath).toString
var AntlrLexerSplitter splitter = new AntlrLexerSplitter(content)
splitter.setCasesPerSpecialStateSwitch(options.getCasesPerSpecialStateSwitch());
fsa.generateFile(lexer.javaPath, splitter.transform)
}
def protected void splitParserClassFile(IXtextGeneratorFileSystemAccess fsa, TypeReference parser) {
val content = fsa.readTextFile(parser.javaPath).toString
val splitter = new AntlrParserSplitter(content, getOptions.fieldsPerClass)
val extractor = new PartialClassExtractor(splitter.transform, getOptions.methodsPerClass)
fsa.generateFile(parser.javaPath, extractor.transform)
}
def protected void simplifyUnorderedGroupPredicatesIfRequired(Grammar grammar, IXtextGeneratorFileSystemAccess fsa, TypeReference parser) {
if (containsUnorderedGroup(grammar) || hasParameterizedRules(grammar)) {
simplifyUnorderedGroupPredicates(fsa, parser)
}
}
def protected boolean hasParameterizedRules(Grammar grammar) {
for (ParserRule rule : GrammarUtil::allParserRules(grammar)) {
if (!rule.getParameters().isEmpty()) {
return true
}
}
return false
}
def protected void simplifyUnorderedGroupPredicates(IXtextGeneratorFileSystemAccess fsa, TypeReference parser) {
val content = fsa.readTextFile(parser.javaPath).toString
var UnorderedGroupsSplitter splitter = new UnorderedGroupsSplitter(content)
var String transformed = splitter.transform()
var SyntacticPredicateFixup fixup = new SyntacticPredicateFixup(transformed)
transformed = fixup.transform()
var BacktrackingGuardForUnorderedGroupsRemover remover = new BacktrackingGuardForUnorderedGroupsRemover(transformed)
var String newContent = remover.transform()
fsa.generateFile(parser.javaPath, newContent)
}
def protected void suppressWarnings(IXtextGeneratorFileSystemAccess fsa, TypeReference type) {
val content = fsa.readTextFile(type.javaPath).toString
val newContent = new SuppressWarningsProcessor().process(content)
fsa.generateFile(type.javaPath, newContent)
}
def protected void suppressWarnings(IXtextGeneratorFileSystemAccess fsa, TypeReference... types) {
types.forEach[suppressWarnings(fsa, it)]
}
def protected void normalizeLineDelimiters(IXtextGeneratorFileSystemAccess fsa, TypeReference type) {
var String content = fsa.readTextFile(type.javaPath).toString
content = newLineNormalizer.postProcess(fsa.getURI(type.javaPath), content).toString
// Antlr tries to outsmart us by using a line length that depends on the system
// line delimiter when it splits a very long String (encoded DFA) into a
// string concatenation
// Here we join these lines again.
content = content.replaceAll("\"\\+(\\r)?\\n\\s+\"", "")
fsa.generateFile(type.javaPath, content)
}
def protected void normalizeLineDelimiters(IXtextGeneratorFileSystemAccess fsa, TypeReference... types) {
types.forEach[normalizeLineDelimiters(fsa, it)]
}
def protected void normalizeTokens(IXtextGeneratorFileSystemAccess fsa, String tokenFile) {
var content = fsa.readTextFile(tokenFile).toString
content = newLineNormalizer.postProcess(fsa.getURI(tokenFile), content).toString
val splitted = Strings.split(content, codeConfig.lineDelimiter)
Collections.sort(splitted)
content = Strings.concat(codeConfig.lineDelimiter, splitted) + codeConfig.lineDelimiter
fsa.generateFile(tokenFile, content)
}
def protected void splitParserAndLexerIfEnabled(IXtextGeneratorFileSystemAccess fsa, TypeReference parser, TypeReference lexer) {
improveCodeQuality(fsa, lexer, parser)
if (getOptions().isClassSplitting()) {
splitLexerClassFile(fsa, lexer)
splitParserClassFile(fsa, parser)
}
}
def protected void improveCodeQuality(IXtextGeneratorFileSystemAccess fsa, TypeReference lexer, TypeReference parser) {
improveLexerCodeQuality(fsa, lexer)
improveParserCodeQuality(fsa, parser)
}
def protected void improveParserCodeQuality(IXtextGeneratorFileSystemAccess fsa, TypeReference parser) {
var parserContent = fsa.readTextFile(parser.javaPath).toString
parserContent = codeQualityHelper.stripUnnecessaryComments(parserContent, options)
parserContent = codeQualityHelper.removeDuplicateBitsets(parserContent, options)
parserContent = codeQualityHelper.removeDuplicateDFAs(parserContent, options)
fsa.generateFile(parser.javaPath, parserContent)
}
def protected void improveLexerCodeQuality(IXtextGeneratorFileSystemAccess fsa, TypeReference lexer) {
var lexerContent = fsa.readTextFile(lexer.javaPath).toString
lexerContent = codeQualityHelper.stripUnnecessaryComments(lexerContent, options)
fsa.generateFile(lexer.javaPath, lexerContent)
}
def protected void cleanupLexerTokensFile(AntlrGrammar lexerGrammar, KeywordHelper helper, IXtextGeneratorFileSystemAccess fsa) {
if (options.backtrackLexer) {
val provider = createLexerTokensProvider(lexerGrammar, helper, fsa)
val entries = provider.tokenDefMap.entrySet.iterator
while (entries.hasNext) {
val value = entries.next.value
if(!helper.isKeywordRule(value) && !value.startsWith("RULE_") && !value.startsWith("SUPER_"))
entries.remove
}
val writer = new CharArrayWriter
provider.writeTokenFile(new PrintWriter(writer))
fsa.generateFile(lexerGrammar.tokensFileName, new String(writer.toCharArray))
}
}
def protected MutableTokenDefProvider createLexerTokensProvider(AntlrGrammar lexerGrammar, KeywordHelper helper, IXtextGeneratorFileSystemAccess fsa) {
val provider = new MutableTokenDefProvider(helper, Charset.forName(codeConfig.encoding))
provider.antlrTokenFileProvider = [fsa.readBinaryFile(lexerGrammar.tokensFileName)]
return provider
}
def protected void cleanupParserTokensFile(AntlrGrammar lexerGrammar, AntlrGrammar parserGrammar, KeywordHelper helper, IXtextGeneratorFileSystemAccess fsa) {
val provider= createLexerTokensProvider(lexerGrammar, helper, fsa)
for (entry : provider.tokenDefMap.entrySet) {
val value = entry.value
if (helper.isKeywordRule(value)) {
val keywordAsAntlrString = AntlrGrammarGenUtil.toAntlrString(helper.getKeywordValue(value))
entry.setValue("'" + keywordAsAntlrString + "'")
} else if (value.startsWith("'")) {
entry.setValue("'" + AntlrGrammarGenUtil.toAntlrString(value) + "'")
}
}
val writer = new CharArrayWriter
provider.writeTokenFile(new PrintWriter(writer))
fsa.generateFile(parserGrammar.tokensFileName, new String(writer.toCharArray))
}
def protected void removeBackTrackingGuards(IXtextGeneratorFileSystemAccess fsa, TypeReference parser, int lookaheadThreshold) {
val content = fsa.readTextFile(parser.javaPath).toString
val remover = new BacktrackingGuardRemover(content, lookaheadThreshold)
val newContent = remover.transform
fsa.generateFile(parser.javaPath, newContent)
}
def protected boolean containsUnorderedGroup(Grammar grammar) {
for (ParserRule rule : GrammarUtil::allParserRules(grammar)) {
if (Iterators::filter(rule.eAllContents(), UnorderedGroup).hasNext()) {
return true
}
}
return false
}
}

View file

@ -0,0 +1,105 @@
/**
* 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.xtext.generator.parser.antlr;
import org.eclipse.xtext.Grammar;
import org.eclipse.xtext.GrammarUtil;
import org.eclipse.xtext.xtext.generator.XtextGeneratorNaming;
import org.eclipse.xtext.xtext.generator.model.TypeReference;
import com.google.inject.Inject;
import com.google.inject.Singleton;
@Singleton
public class GrammarNaming {
@Inject
private XtextGeneratorNaming xtextGeneratorNaming;
public boolean isCombinedGrammar(Grammar it) {
return CombinedGrammarMarker.findInEmfObject(it).isCombinedGrammar();
}
protected String getParserPackage(Grammar it) {
return xtextGeneratorNaming.getRuntimeBasePackage(it) + ".parser.antlr";
}
protected String getInternalParserPackage(Grammar it) {
return getParserPackage(it) + ".internal";
}
protected String getInternalLexerPackage(Grammar it) {
return getParserPackage(it) + ".lexer";
}
public AntlrGrammar getParserGrammar(Grammar it) {
StringBuilder builder = new StringBuilder();
builder.append(getGrammarNamePrefix(it));
builder.append("Internal");
builder.append(GrammarUtil.getSimpleName(it));
if (!isCombinedGrammar(it)) {
builder.append("Parser");
}
return new AntlrGrammar(getInternalParserPackage(it), builder.toString());
}
public AntlrGrammar getLexerGrammar(Grammar it) {
if (isCombinedGrammar(it)) {
return getParserGrammar(it);
} else {
return new AntlrGrammar(getInternalLexerPackage(it),
getGrammarNamePrefix(it) + "Internal" + GrammarUtil.getSimpleName(it) + "Lexer");
}
}
protected String getGrammarNamePrefix(Grammar it) {
return "";
}
public TypeReference getLexerClass(Grammar it) {
StringBuilder builder = new StringBuilder();
builder.append(getLexerGrammar(it).getSimpleName());
if (isCombinedGrammar(it)) {
builder.append("Lexer");
}
return new TypeReference(getLexerGrammar(it).getPackageName(), builder.toString());
}
public TypeReference getLexerSuperClass(Grammar it) {
return new TypeReference("org.eclipse.xtext.parser.antlr.Lexer");
}
public TypeReference getParserClass(Grammar it) {
return new TypeReference(getParserPackage(it), GrammarUtil.getSimpleName(it) + "Parser");
}
public TypeReference getParserSuperClass(Grammar it, boolean partialParsing) {
return new TypeReference("org.eclipse.xtext.parser.antlr.AbstractAntlrParser");
}
public TypeReference getInternalParserClass(Grammar it) {
StringBuilder builder = new StringBuilder();
builder.append(getParserGrammar(it).getSimpleName());
if (isCombinedGrammar(it)) {
builder.append("Parser");
}
return new TypeReference(getParserGrammar(it).getPackageName(), builder.toString());
}
public TypeReference getInternalParserSuperClass(Grammar it) {
return new TypeReference("org.eclipse.xtext.parser.antlr.AbstractInternalAntlrParser");
}
public TypeReference getAntlrTokenFileProviderClass(Grammar it) {
return new TypeReference(getParserPackage(it), GrammarUtil.getSimpleName(it) + "AntlrTokenFileProvider");
}
public TypeReference getTokenSourceClass(Grammar it) {
return new TypeReference(getParserPackage(it), GrammarUtil.getSimpleName(it) + "TokenSource");
}
}

View file

@ -1,89 +0,0 @@
/*******************************************************************************
* Copyright (c) 2015 itemis AG (http://www.itemis.eu) and others.
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0.
*
* SPDX-License-Identifier: EPL-2.0
*******************************************************************************/
package org.eclipse.xtext.xtext.generator.parser.antlr
import com.google.inject.Inject
import com.google.inject.Singleton
import org.eclipse.xtext.Grammar
import org.eclipse.xtext.xtext.generator.XtextGeneratorNaming
import org.eclipse.xtext.xtext.generator.model.TypeReference
import static extension org.eclipse.xtext.GrammarUtil.*
@Singleton
class GrammarNaming {
@Inject
extension XtextGeneratorNaming
def isCombinedGrammar(Grammar it) {
CombinedGrammarMarker.findInEmfObject(it).isCombinedGrammar
}
protected def String getParserPackage(Grammar it) {
runtimeBasePackage + ".parser.antlr"
}
protected def String getInternalParserPackage(Grammar it) {
parserPackage + ".internal"
}
protected def String getInternalLexerPackage(Grammar it) {
parserPackage + ".lexer"
}
def AntlrGrammar getParserGrammar(Grammar it) {
new AntlrGrammar(internalParserPackage, '''«grammarNamePrefix»Internal«simpleName»«IF !combinedGrammar»Parser«ENDIF»''')
}
def AntlrGrammar getLexerGrammar(Grammar it) {
if (combinedGrammar) {
getParserGrammar
} else {
new AntlrGrammar(internalLexerPackage, '''«grammarNamePrefix»Internal«simpleName»Lexer''')
}
}
protected def String getGrammarNamePrefix(Grammar it) {
""
}
def TypeReference getLexerClass(Grammar it) {
new TypeReference(lexerGrammar.packageName, '''«lexerGrammar.simpleName»«IF combinedGrammar»Lexer«ENDIF»''')
}
def TypeReference getLexerSuperClass(Grammar it) {
new TypeReference("org.eclipse.xtext.parser.antlr.Lexer")
}
def TypeReference getParserClass(Grammar it) {
new TypeReference(parserPackage, '''«simpleName»Parser''')
}
def TypeReference getParserSuperClass(Grammar it, boolean partialParsing) {
new TypeReference("org.eclipse.xtext.parser.antlr.AbstractAntlrParser")
}
def TypeReference getInternalParserClass(Grammar it) {
new TypeReference(parserGrammar.packageName, '''«parserGrammar.simpleName»«IF combinedGrammar»Parser«ENDIF»''')
}
def TypeReference getInternalParserSuperClass(Grammar it) {
new TypeReference("org.eclipse.xtext.parser.antlr.AbstractInternalAntlrParser")
}
def TypeReference getAntlrTokenFileProviderClass(Grammar it) {
new TypeReference(parserPackage, '''«simpleName»AntlrTokenFileProvider''')
}
def TypeReference getTokenSourceClass(Grammar it) {
new TypeReference(parserPackage, simpleName + "TokenSource")
}
}

View file

@ -1,457 +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.xtext.generator;
import com.google.common.base.Joiner;
import com.google.common.collect.Lists;
import com.google.inject.Binder;
import com.google.inject.Inject;
import com.google.inject.Injector;
import com.google.inject.Provider;
import java.io.File;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import org.apache.log4j.Logger;
import org.eclipse.emf.common.util.Diagnostic;
import org.eclipse.emf.common.util.DiagnosticChain;
import org.eclipse.emf.common.util.TreeIterator;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.emf.ecore.EValidator;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.xtend.lib.annotations.AccessorType;
import org.eclipse.xtend.lib.annotations.Accessors;
import org.eclipse.xtext.AbstractMetamodelDeclaration;
import org.eclipse.xtext.Grammar;
import org.eclipse.xtext.GrammarUtil;
import org.eclipse.xtext.ReferencedMetamodel;
import org.eclipse.xtext.XtextPackage;
import org.eclipse.xtext.nodemodel.INode;
import org.eclipse.xtext.nodemodel.util.NodeModelUtils;
import org.eclipse.xtext.resource.IResourceDescription;
import org.eclipse.xtext.resource.IResourceServiceProvider;
import org.eclipse.xtext.resource.XtextResource;
import org.eclipse.xtext.resource.impl.ResourceDescriptionsData;
import org.eclipse.xtext.xbase.lib.CollectionLiterals;
import org.eclipse.xtext.xbase.lib.Conversions;
import org.eclipse.xtext.xbase.lib.IterableExtensions;
import org.eclipse.xtext.xbase.lib.Pure;
import org.eclipse.xtext.xtext.RuleNames;
import org.eclipse.xtext.xtext.generator.CodeConfig;
import org.eclipse.xtext.xtext.generator.CompositeGeneratorFragment2;
import org.eclipse.xtext.xtext.generator.IXtextGeneratorFragment;
import org.eclipse.xtext.xtext.generator.IXtextGeneratorLanguage;
import org.eclipse.xtext.xtext.generator.ImplicitFragment;
import org.eclipse.xtext.xtext.generator.XtextGeneratorResourceSetInitializer;
import org.eclipse.xtext.xtext.generator.model.GuiceModuleAccess;
import org.eclipse.xtext.xtext.generator.model.StandaloneSetupAccess;
import org.eclipse.xtext.xtext.generator.model.project.IXtextProjectConfig;
/**
* Configuration for an Xtext language. Use this class if you need to specify exactly which generator
* fragments you want to include, or alternatively {@link StandardLanguage} to work with the standard
* fragments.
*
* <p>The most important property is {@code name}, which should be set to the language name exactly
* as specified in the grammar file. If the default grammar resolution based on the name does not
* work in your particular scenario, set the {@code grammarUri} property instead. Furthermore,
* use {@code fileExtensions} to specify the file extensions for your language.</p>
*
* <p>Generator fragments can be added with the {@code fragment} property. See {@link StandardLanguage}
* for a list of useful fragments.</p>
*
* @noextend This class should not be extended by clients.
*/
@SuppressWarnings("all")
public class XtextGeneratorLanguage extends CompositeGeneratorFragment2 implements IXtextGeneratorLanguage {
private static final Logger LOG = Logger.getLogger(XtextGeneratorLanguage.class);
private String grammarUri;
private String name;
private Boolean generateXtendStubs;
@Accessors(AccessorType.PUBLIC_GETTER)
private Grammar grammar;
@Accessors(AccessorType.PUBLIC_GETTER)
private RuleNames ruleNames;
@Accessors(AccessorType.PUBLIC_GETTER)
private List<String> fileExtensions;
@Accessors(AccessorType.PUBLIC_GETTER)
private List<String> referencedResources = CollectionLiterals.<String>newArrayList();
@Accessors
private ResourceSet resourceSet;
@Accessors
private com.google.inject.Module guiceModule = ((com.google.inject.Module) (Binder it) -> {
});
@Accessors
private final StandaloneSetupAccess runtimeGenSetup = new StandaloneSetupAccess();
@Accessors
private final GuiceModuleAccess runtimeGenModule = new GuiceModuleAccess();
@Accessors
private final GuiceModuleAccess ideGenModule = new GuiceModuleAccess();
@Accessors
private final GuiceModuleAccess eclipsePluginGenModule = new GuiceModuleAccess();
@Accessors
private final GuiceModuleAccess webGenModule = new GuiceModuleAccess();
@Inject
private Provider<ResourceSet> resourceSetProvider;
@Inject
private IXtextProjectConfig projectConfig;
@Inject
private CodeConfig codeConfig;
@Inject
private XtextGeneratorResourceSetInitializer resourceSetInitializer;
/**
* The URI of the grammar file. Use this property if the automatic grammar resolution based on {@link #setName(String)}
* does not work in your particular scenario.
*/
public void setGrammarUri(final String uri) {
this.grammarUri = uri;
}
public String getGrammarUri() {
String _elvis = null;
if (this.grammarUri != null) {
_elvis = this.grammarUri;
} else {
String _path = this.projectConfig.getRuntime().getSrc().getPath();
String _replace = this.name.replace(".", "/");
String _plus = (_replace + ".xtext");
String _string = new File(_path, _plus).toURI().toString();
_elvis = _string;
}
return _elvis;
}
/**
* The language name exactly as specified in the grammar.
*/
public void setName(final String name) {
this.name = name;
}
/**
* Either a single file extension or a comma-separated list of extensions for which the language
* shall be registered.
*/
public void setFileExtensions(final String fileExtensions) {
this.fileExtensions = IterableExtensions.<String>toList(((Iterable<String>)Conversions.doWrapArray(fileExtensions.trim().split("\\s*,\\s*"))));
}
/**
* Add a resource to be included in the resource set that will be used to load the grammar file.
* This is often necessary if additional Ecore models are referenced by the grammar.
*/
public void addReferencedResource(final String referencedResource) {
this.referencedResources.add(referencedResource);
}
@Override
public List<String> getFileExtensions() {
if (((this.fileExtensions == null) || this.fileExtensions.isEmpty())) {
this.setFileExtensions(GrammarUtil.getSimpleName(this.grammar).toLowerCase());
XtextGeneratorLanguage.LOG.info((("No explicit fileExtensions configured. Using \'*." + this.fileExtensions) + "\'."));
}
return this.fileExtensions;
}
/**
* @deprecated Use {@link CodeConfig#setPreferXtendStubs(boolean)} instead
*/
@Deprecated
public void setGenerateXtendStubs(final Boolean generateXtendStubs) {
this.generateXtendStubs = generateXtendStubs;
}
/**
* @deprecated Use {@link CodeConfig#isPreferXtendStubs()} instead
*/
@Deprecated
@Override
public boolean isGenerateXtendStubs() {
boolean _xifexpression = false;
if ((this.generateXtendStubs != null)) {
_xifexpression = this.generateXtendStubs.booleanValue();
} else {
_xifexpression = this.codeConfig.isPreferXtendStubs();
}
return _xifexpression;
}
@Override
public void initialize(final Injector injector) {
this.getFragments().addAll(0, this.getImplicitFragments());
injector.injectMembers(this);
if ((this.resourceSet == null)) {
this.resourceSet = this.resourceSetProvider.get();
}
this.resourceSetInitializer.initialize(this.resourceSet, this.referencedResources);
boolean _isEmpty = this.resourceSet.getResources().isEmpty();
boolean _not = (!_isEmpty);
if (_not) {
this.installIndex();
{
int i = 0;
int size = this.resourceSet.getResources().size();
boolean _while = (i < size);
while (_while) {
{
final Resource res = this.resourceSet.getResources().get(i);
boolean _isEmpty_1 = res.getContents().isEmpty();
if (_isEmpty_1) {
URI _uRI = res.getURI();
String _plus = ("Error loading \'" + _uRI);
String _plus_1 = (_plus + "\'");
XtextGeneratorLanguage.LOG.error(_plus_1);
} else {
boolean _isEmpty_2 = res.getErrors().isEmpty();
boolean _not_1 = (!_isEmpty_2);
if (_not_1) {
URI _uRI_1 = res.getURI();
String _plus_2 = ("Error loading \'" + _uRI_1);
String _plus_3 = (_plus_2 + "\':\n");
String _join = Joiner.on("\n").join(res.getErrors());
String _plus_4 = (_plus_3 + _join);
XtextGeneratorLanguage.LOG.error(_plus_4);
}
}
}
i++;
_while = (i < size);
}
}
EcoreUtil.resolveAll(this.resourceSet);
}
String _grammarUri = this.getGrammarUri();
boolean _tripleEquals = (_grammarUri == null);
if (_tripleEquals) {
throw new IllegalStateException("No grammarUri or language name given");
}
Resource _resource = this.resourceSet.getResource(URI.createURI(this.getGrammarUri()), true);
final XtextResource resource = ((XtextResource) _resource);
boolean _isEmpty_1 = resource.getContents().isEmpty();
if (_isEmpty_1) {
String _grammarUri_1 = this.getGrammarUri();
String _plus = ("Couldn\'t load grammar for \'" + _grammarUri_1);
String _plus_1 = (_plus + "\'.");
throw new IllegalArgumentException(_plus_1);
}
boolean _isEmpty_2 = resource.getErrors().isEmpty();
boolean _not_1 = (!_isEmpty_2);
if (_not_1) {
XtextGeneratorLanguage.LOG.error(resource.getErrors());
String _grammarUri_2 = this.getGrammarUri();
String _plus_2 = ("Problem parsing \'" + _grammarUri_2);
String _plus_3 = (_plus_2 + "\':\n");
String _join = Joiner.on("\n").join(resource.getErrors());
String _plus_4 = (_plus_3 + _join);
throw new IllegalStateException(_plus_4);
}
EObject _get = resource.getContents().get(0);
final Grammar grammar = ((Grammar) _get);
this.validateGrammar(grammar);
this.initialize(grammar);
super.initialize(injector);
}
protected List<? extends IXtextGeneratorFragment> getImplicitFragments() {
final ArrayList<ImplicitFragment> fragments = CollectionLiterals.<ImplicitFragment>newArrayList();
ImplicitFragment _implicitFragment = new ImplicitFragment();
fragments.add(_implicitFragment);
return fragments;
}
public void initialize(final Grammar grammar) {
this.grammar = grammar;
this.ruleNames = RuleNames.getRuleNames(grammar, true);
}
private void installIndex() {
List<IResourceDescription> _emptyList = Collections.<IResourceDescription>emptyList();
final ResourceDescriptionsData index = new ResourceDescriptionsData(_emptyList);
final ArrayList<Resource> resources = Lists.<Resource>newArrayList(this.resourceSet.getResources());
for (final Resource resource : resources) {
this.index(resource, resource.getURI(), index);
}
ResourceDescriptionsData.ResourceSetAdapter.installResourceDescriptionsData(this.resourceSet, index);
}
private void index(final Resource resource, final URI uri, final ResourceDescriptionsData index) {
final IResourceServiceProvider serviceProvider = IResourceServiceProvider.Registry.INSTANCE.getResourceServiceProvider(uri);
if ((serviceProvider != null)) {
final IResourceDescription resourceDescription = serviceProvider.getResourceDescriptionManager().getResourceDescription(resource);
if ((resourceDescription != null)) {
index.addDescription(uri, resourceDescription);
}
}
}
protected void validateGrammar(final Grammar grammar) {
this.validateAllImports(grammar);
final EValidator validator = EValidator.Registry.INSTANCE.getEValidator(XtextPackage.eINSTANCE);
if ((validator != null)) {
final DiagnosticChain chain = new DiagnosticChain() {
@Override
public void add(final Diagnostic diagnostic) {
int _severity = diagnostic.getSeverity();
boolean _equals = (_severity == Diagnostic.ERROR);
if (_equals) {
String _name = grammar.getName();
String _plus = ("Validation Error in " + _name);
final String grammarName = (_plus + ": ");
Throwable _exception = diagnostic.getException();
boolean _tripleEquals = (_exception == null);
if (_tripleEquals) {
String _message = diagnostic.getMessage();
String _plus_1 = (grammarName + _message);
throw new IllegalStateException(_plus_1);
} else {
String _message_1 = diagnostic.getMessage();
String _plus_2 = (grammarName + _message_1);
Throwable _exception_1 = diagnostic.getException();
throw new IllegalStateException(_plus_2, _exception_1);
}
}
}
@Override
public void addAll(final Diagnostic diagnostic) {
this.add(diagnostic);
}
@Override
public void merge(final Diagnostic diagnostic) {
throw new UnsupportedOperationException();
}
};
validator.validate(grammar, chain, null);
final TreeIterator<EObject> iterator = grammar.eAllContents();
while (iterator.hasNext()) {
EObject _next = iterator.next();
HashMap<Object, Object> _hashMap = new HashMap<Object, Object>();
validator.validate(_next, chain, _hashMap);
}
}
}
protected void validateAllImports(final Grammar grammar) {
List<AbstractMetamodelDeclaration> _allMetamodelDeclarations = GrammarUtil.allMetamodelDeclarations(grammar);
for (final AbstractMetamodelDeclaration amd : _allMetamodelDeclarations) {
if ((amd instanceof ReferencedMetamodel)) {
this.validateReferencedMetamodel(((ReferencedMetamodel)amd));
}
}
}
protected void validateReferencedMetamodel(final ReferencedMetamodel ref) {
if (((ref.getEPackage() != null) && (!ref.getEPackage().eIsProxy()))) {
return;
}
final EReference eref = XtextPackage.Literals.ABSTRACT_METAMODEL_DECLARATION__EPACKAGE;
final List<INode> nodes = NodeModelUtils.findNodesForFeature(ref, eref);
String _xifexpression = null;
boolean _isEmpty = nodes.isEmpty();
if (_isEmpty) {
_xifexpression = "(unknown)";
} else {
_xifexpression = NodeModelUtils.getTokenText(nodes.get(0));
}
final String refName = _xifexpression;
final String grammarName = GrammarUtil.getGrammar(ref).getName();
final String msg = ((((("The EPackage " + refName) + " in grammar ") + grammarName) + " could not be found. ") + "You might want to register that EPackage in your workflow file.");
throw new IllegalStateException(msg);
}
@Pure
@Override
public Grammar getGrammar() {
return this.grammar;
}
@Pure
public RuleNames getRuleNames() {
return this.ruleNames;
}
@Pure
public List<String> getReferencedResources() {
return this.referencedResources;
}
@Pure
@Override
public ResourceSet getResourceSet() {
return this.resourceSet;
}
public void setResourceSet(final ResourceSet resourceSet) {
this.resourceSet = resourceSet;
}
@Pure
public com.google.inject.Module getGuiceModule() {
return this.guiceModule;
}
public void setGuiceModule(final com.google.inject.Module guiceModule) {
this.guiceModule = guiceModule;
}
@Pure
@Override
public StandaloneSetupAccess getRuntimeGenSetup() {
return this.runtimeGenSetup;
}
@Pure
@Override
public GuiceModuleAccess getRuntimeGenModule() {
return this.runtimeGenModule;
}
@Pure
@Override
public GuiceModuleAccess getIdeGenModule() {
return this.ideGenModule;
}
@Pure
@Override
public GuiceModuleAccess getEclipsePluginGenModule() {
return this.eclipsePluginGenModule;
}
@Pure
@Override
public GuiceModuleAccess getWebGenModule() {
return this.webGenModule;
}
}

View file

@ -1,316 +0,0 @@
/**
* Copyright (c) 2015, 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.xtext.generator.model.project;
import com.google.common.base.Objects;
import java.util.function.Consumer;
import org.eclipse.emf.mwe2.runtime.Mandatory;
import org.eclipse.xtend.lib.annotations.Accessors;
import org.eclipse.xtext.xbase.lib.Pure;
import org.eclipse.xtext.xtext.generator.Issues;
import org.eclipse.xtext.xtext.generator.model.ManifestAccess;
import org.eclipse.xtext.xtext.generator.model.PluginXmlAccess;
import org.eclipse.xtext.xtext.generator.model.project.BundleProjectConfig;
import org.eclipse.xtext.xtext.generator.model.project.RuntimeProjectConfig;
import org.eclipse.xtext.xtext.generator.model.project.SubProjectConfig;
import org.eclipse.xtext.xtext.generator.model.project.WebProjectConfig;
import org.eclipse.xtext.xtext.generator.model.project.XtextProjectConfig;
/**
* Specialized project configuration that uses standard names and paths. Usually it is sufficient to
* set the {@code baseName} and {@code rootPath} properties and to enable the required subprojects.
*
* @noextend This class should not be extended by clients.
*/
@Accessors
@SuppressWarnings("all")
public class StandardProjectConfig extends XtextProjectConfig {
/**
* set to {@code true} by the project wizard(s) in case "Maven/Gradle" source layout is selected.
*/
private boolean mavenLayout;
private boolean createEclipseMetaData;
private String rootPath;
private String baseName;
/**
* The base name of the project, which is usually equal to the runtime subproject.
*/
@Mandatory
public String setBaseName(final String baseName) {
return this.baseName = baseName;
}
/**
* The root path, usually {@code ".."}.
*/
@Mandatory
public String setRootPath(final String rootPath) {
return this.rootPath = rootPath;
}
@Override
public void checkConfiguration(final Issues issues) {
super.checkConfiguration(issues);
if ((this.rootPath == null)) {
issues.addError("The property \'rootPath\' must be set", this);
}
if ((this.baseName == null)) {
issues.addError("The property \'baseName\' must be set", this);
}
}
@Override
public void setDefaults() {
super.setDefaults();
final Consumer<SubProjectConfig> _function = (SubProjectConfig it) -> {
String _name = it.getName();
boolean _tripleEquals = (_name == null);
if (_tripleEquals) {
it.setName(this.computeName(it));
}
String _rootPath = it.getRootPath();
boolean _tripleEquals_1 = (_rootPath == null);
if (_tripleEquals_1) {
it.setRoot(this.computeRoot(it));
}
String _metaInfPath = it.getMetaInfPath();
boolean _tripleEquals_2 = (_metaInfPath == null);
if (_tripleEquals_2) {
it.setMetaInf(this.computeMetaInf(it));
}
String _srcPath = it.getSrcPath();
boolean _tripleEquals_3 = (_srcPath == null);
if (_tripleEquals_3) {
it.setSrc(this.computeSrc(it));
}
String _srcGenPath = it.getSrcGenPath();
boolean _tripleEquals_4 = (_srcGenPath == null);
if (_tripleEquals_4) {
it.setSrcGen(this.computeSrcGen(it));
}
String _iconsPath = it.getIconsPath();
boolean _tripleEquals_5 = (_iconsPath == null);
if (_tripleEquals_5) {
it.setIcons(this.computeIcons(it));
}
if ((it instanceof BundleProjectConfig)) {
if (this.createEclipseMetaData) {
ManifestAccess _manifest = ((BundleProjectConfig)it).getManifest();
boolean _tripleEquals_6 = (_manifest == null);
if (_tripleEquals_6) {
((BundleProjectConfig)it).setManifest(this.newManifestAccess());
}
PluginXmlAccess _pluginXml = ((BundleProjectConfig)it).getPluginXml();
boolean _tripleEquals_7 = (_pluginXml == null);
if (_tripleEquals_7) {
((BundleProjectConfig)it).setPluginXml(this.newPluginXmlAccess());
}
}
}
if ((it instanceof RuntimeProjectConfig)) {
String _ecoreModelPath = ((RuntimeProjectConfig)it).getEcoreModelPath();
boolean _tripleEquals_8 = (_ecoreModelPath == null);
if (_tripleEquals_8) {
((RuntimeProjectConfig)it).setEcoreModel(this.computeEcoreModel(((RuntimeProjectConfig)it)));
}
}
if ((it instanceof WebProjectConfig)) {
String _assetsPath = ((WebProjectConfig)it).getAssetsPath();
boolean _tripleEquals_9 = (_assetsPath == null);
if (_tripleEquals_9) {
((WebProjectConfig)it).setAssets(this.computeAssets(((WebProjectConfig)it)));
}
}
};
this.getEnabledProjects().forEach(_function);
}
protected String computeName(final SubProjectConfig project) {
String _switchResult = null;
boolean _matched = false;
RuntimeProjectConfig _runtime = this.getRuntime();
if (Objects.equal(project, _runtime)) {
_matched=true;
_switchResult = this.baseName;
}
if (!_matched) {
BundleProjectConfig _runtimeTest = this.getRuntimeTest();
if (Objects.equal(project, _runtimeTest)) {
_matched=true;
String _xifexpression = null;
if ((!this.mavenLayout)) {
_xifexpression = (this.baseName + ".tests");
} else {
_xifexpression = this.baseName;
}
_switchResult = _xifexpression;
}
}
if (!_matched) {
BundleProjectConfig _genericIde = this.getGenericIde();
if (Objects.equal(project, _genericIde)) {
_matched=true;
_switchResult = (this.baseName + ".ide");
}
}
if (!_matched) {
BundleProjectConfig _eclipsePlugin = this.getEclipsePlugin();
if (Objects.equal(project, _eclipsePlugin)) {
_matched=true;
_switchResult = (this.baseName + ".ui");
}
}
if (!_matched) {
BundleProjectConfig _eclipsePluginTest = this.getEclipsePluginTest();
if (Objects.equal(project, _eclipsePluginTest)) {
_matched=true;
String _xifexpression_1 = null;
if ((!this.mavenLayout)) {
_xifexpression_1 = (this.baseName + ".ui.tests");
} else {
_xifexpression_1 = (this.baseName + ".ui");
}
_switchResult = _xifexpression_1;
}
}
if (!_matched) {
WebProjectConfig _web = this.getWeb();
if (Objects.equal(project, _web)) {
_matched=true;
_switchResult = (this.baseName + ".web");
}
}
return _switchResult;
}
protected String computeRoot(final SubProjectConfig project) {
String _name = project.getName();
return ((this.rootPath + "/") + _name);
}
/**
* In case of "Maven/Gradle" source layout the src outlet is named 'src/main/java',
* test classes go into 'src/test/java' instead of any dedicated '...tests' project.
*/
protected String computeSrc(final SubProjectConfig project) {
String _rootPath = project.getRootPath();
String _plus = (_rootPath + "/");
String _xifexpression = null;
if (this.mavenLayout) {
String _computeSourceSet = this.computeSourceSet(project);
String _plus_1 = ("src/" + _computeSourceSet);
_xifexpression = (_plus_1 + "/java");
} else {
_xifexpression = "src";
}
return (_plus + _xifexpression);
}
/**
* In case of "Maven/Gradle" source layout the srcGen outlet is named 'src/main/xtext-gen',
* test-related srcGen classes go into 'src/test/xtext-gen' instead of any dedicated '...tests' project.
* Don't confuse it with 'src/main/xtend-gen'!
*/
protected String computeSrcGen(final SubProjectConfig project) {
String _rootPath = project.getRootPath();
String _plus = (_rootPath + "/");
String _xifexpression = null;
if (this.mavenLayout) {
String _computeSourceSet = this.computeSourceSet(project);
String _plus_1 = ("src/" + _computeSourceSet);
_xifexpression = (_plus_1 + "/xtext-gen");
} else {
_xifexpression = "src-gen";
}
return (_plus + _xifexpression);
}
protected String computeMetaInf(final SubProjectConfig project) {
String _rootPath = project.getRootPath();
String _plus = (_rootPath + "/");
String _xifexpression = null;
if (this.mavenLayout) {
String _computeSourceSet = this.computeSourceSet(project);
String _plus_1 = ("src/" + _computeSourceSet);
_xifexpression = (_plus_1 + "/resources/META-INF");
} else {
_xifexpression = "META-INF";
}
return (_plus + _xifexpression);
}
protected String computeEcoreModel(final RuntimeProjectConfig project) {
String _rootPath = project.getRootPath();
String _plus = (_rootPath + "/");
return (_plus + "model/generated");
}
protected String computeAssets(final WebProjectConfig project) {
String _rootPath = project.getRootPath();
String _plus = (_rootPath + "/");
String _xifexpression = null;
if (this.mavenLayout) {
String _computeSourceSet = this.computeSourceSet(project);
String _plus_1 = ("src/" + _computeSourceSet);
_xifexpression = (_plus_1 + "/webapp");
} else {
_xifexpression = "WebRoot";
}
return (_plus + _xifexpression);
}
protected String computeSourceSet(final SubProjectConfig project) {
String _xifexpression = null;
boolean _contains = this.getTestProjects().contains(project);
if (_contains) {
_xifexpression = "test";
} else {
_xifexpression = "main";
}
return _xifexpression;
}
protected String computeIcons(final SubProjectConfig project) {
String _rootPath = project.getRootPath();
String _plus = (_rootPath + "/");
return (_plus + "icons");
}
@Pure
public boolean isMavenLayout() {
return this.mavenLayout;
}
public void setMavenLayout(final boolean mavenLayout) {
this.mavenLayout = mavenLayout;
}
@Pure
public boolean isCreateEclipseMetaData() {
return this.createEclipseMetaData;
}
public void setCreateEclipseMetaData(final boolean createEclipseMetaData) {
this.createEclipseMetaData = createEclipseMetaData;
}
@Pure
public String getRootPath() {
return this.rootPath;
}
@Pure
public String getBaseName() {
return this.baseName;
}
}

View file

@ -1,358 +0,0 @@
/**
* Copyright (c) 2015 itemis AG (http://www.itemis.eu) and others.
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0.
*
* SPDX-License-Identifier: EPL-2.0
*/
package org.eclipse.xtext.xtext.generator.parser.antlr;
import com.google.common.collect.Iterators;
import com.google.common.collect.Lists;
import com.google.inject.Inject;
import java.io.CharArrayWriter;
import java.io.PrintWriter;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.function.Consumer;
import org.eclipse.xtend.lib.annotations.AccessorType;
import org.eclipse.xtend.lib.annotations.Accessors;
import org.eclipse.xtext.AbstractRule;
import org.eclipse.xtext.Grammar;
import org.eclipse.xtext.GrammarUtil;
import org.eclipse.xtext.ParserRule;
import org.eclipse.xtext.UnorderedGroup;
import org.eclipse.xtext.generator.LineSeparatorHarmonizer;
import org.eclipse.xtext.parser.antlr.IAntlrTokenFileProvider;
import org.eclipse.xtext.util.Strings;
import org.eclipse.xtext.xbase.lib.CollectionLiterals;
import org.eclipse.xtext.xbase.lib.Conversions;
import org.eclipse.xtext.xbase.lib.Exceptions;
import org.eclipse.xtext.xbase.lib.Pure;
import org.eclipse.xtext.xtext.generator.AbstractXtextGeneratorFragment;
import org.eclipse.xtext.xtext.generator.CodeConfig;
import org.eclipse.xtext.xtext.generator.Issues;
import org.eclipse.xtext.xtext.generator.model.IXtextGeneratorFileSystemAccess;
import org.eclipse.xtext.xtext.generator.model.TypeReference;
import org.eclipse.xtext.xtext.generator.parser.antlr.AntlrGrammar;
import org.eclipse.xtext.xtext.generator.parser.antlr.AntlrGrammarGenUtil;
import org.eclipse.xtext.xtext.generator.parser.antlr.AntlrOptions;
import org.eclipse.xtext.xtext.generator.parser.antlr.AntlrToolFacade;
import org.eclipse.xtext.xtext.generator.parser.antlr.KeywordHelper;
import org.eclipse.xtext.xtext.generator.parser.antlr.MutableTokenDefProvider;
import org.eclipse.xtext.xtext.generator.parser.antlr.postProcessing.SuppressWarningsProcessor;
import org.eclipse.xtext.xtext.generator.parser.antlr.splitting.AntlrCodeQualityHelper;
import org.eclipse.xtext.xtext.generator.parser.antlr.splitting.AntlrLexerSplitter;
import org.eclipse.xtext.xtext.generator.parser.antlr.splitting.AntlrParserSplitter;
import org.eclipse.xtext.xtext.generator.parser.antlr.splitting.BacktrackingGuardForUnorderedGroupsRemover;
import org.eclipse.xtext.xtext.generator.parser.antlr.splitting.BacktrackingGuardRemover;
import org.eclipse.xtext.xtext.generator.parser.antlr.splitting.PartialClassExtractor;
import org.eclipse.xtext.xtext.generator.parser.antlr.splitting.SyntacticPredicateFixup;
import org.eclipse.xtext.xtext.generator.parser.antlr.splitting.UnorderedGroupsSplitter;
@SuppressWarnings("all")
public abstract class AbstractAntlrGeneratorFragment2 extends AbstractXtextGeneratorFragment {
@Inject
@Accessors(AccessorType.PROTECTED_GETTER)
private AntlrToolFacade antlrTool;
@Inject
@Accessors(AccessorType.PROTECTED_GETTER)
private AntlrCodeQualityHelper codeQualityHelper;
@Inject
@Accessors(AccessorType.PROTECTED_GETTER)
private LineSeparatorHarmonizer newLineNormalizer;
@Inject
@Accessors(AccessorType.PROTECTED_GETTER)
private CodeConfig codeConfig;
@Accessors
private AntlrOptions options = new AntlrOptions();
private final ArrayList<String> antlrParams = CollectionLiterals.<String>newArrayList();
public void addAntlrParam(final String param) {
this.antlrParams.add(param);
}
public String[] getAntlrParams() {
ArrayList<String> params = Lists.<String>newArrayList(this.antlrParams);
boolean _contains = params.contains("-Xconversiontimeout");
boolean _not = (!_contains);
if (_not) {
params.add(0, "-Xconversiontimeout");
params.add(1, "100000");
}
return ((String[])Conversions.unwrapArray(params, String.class));
}
@Override
public void checkConfiguration(final Issues issues) {
super.checkConfiguration(issues);
boolean _isWorkable = this.antlrTool.isWorkable();
boolean _not = (!_isWorkable);
if (_not) {
issues.addError("\n\n*ATTENTION*\nIt is highly recommended to use ANTLR\'s parser generator (get it from \'http://xtext.itemis.com/\'). \nAs an alternative to ANTLR you could also use the alternative implementation shipped with Xtext.\nTo do so use the generator fragment \'org.eclipse.xtext.generator.parser.packrat.PackratParserFragment\' in your mwe2 file instead.");
}
}
@Override
public void generate() {
this.checkGrammar();
this.doGenerate();
}
protected abstract void doGenerate();
protected void checkGrammar() {
boolean _hasProductionRules = this.hasProductionRules(this.getGrammar());
boolean _not = (!_hasProductionRules);
if (_not) {
throw new IllegalArgumentException("You may not generate an ANTLR parser for a grammar without production rules.");
}
}
protected boolean hasProductionRules(final Grammar grammar) {
AbstractRule firstRule = grammar.getRules().get(0);
return ((firstRule instanceof ParserRule) && (!GrammarUtil.isDatatypeRule(((ParserRule) firstRule))));
}
protected void splitLexerClassFile(final IXtextGeneratorFileSystemAccess fsa, final TypeReference lexer) {
final String content = fsa.readTextFile(lexer.getJavaPath()).toString();
AntlrLexerSplitter splitter = new AntlrLexerSplitter(content);
splitter.setCasesPerSpecialStateSwitch(this.options.getCasesPerSpecialStateSwitch());
fsa.generateFile(lexer.getJavaPath(), splitter.transform());
}
protected void splitParserClassFile(final IXtextGeneratorFileSystemAccess fsa, final TypeReference parser) {
final String content = fsa.readTextFile(parser.getJavaPath()).toString();
int _fieldsPerClass = this.getOptions().getFieldsPerClass();
final AntlrParserSplitter splitter = new AntlrParserSplitter(content, _fieldsPerClass);
String _transform = splitter.transform();
int _methodsPerClass = this.getOptions().getMethodsPerClass();
final PartialClassExtractor extractor = new PartialClassExtractor(_transform, _methodsPerClass);
fsa.generateFile(parser.getJavaPath(), extractor.transform());
}
protected void simplifyUnorderedGroupPredicatesIfRequired(final Grammar grammar, final IXtextGeneratorFileSystemAccess fsa, final TypeReference parser) {
if ((this.containsUnorderedGroup(grammar) || this.hasParameterizedRules(grammar))) {
this.simplifyUnorderedGroupPredicates(fsa, parser);
}
}
protected boolean hasParameterizedRules(final Grammar grammar) {
List<ParserRule> _allParserRules = GrammarUtil.allParserRules(grammar);
for (final ParserRule rule : _allParserRules) {
boolean _isEmpty = rule.getParameters().isEmpty();
boolean _not = (!_isEmpty);
if (_not) {
return true;
}
}
return false;
}
protected void simplifyUnorderedGroupPredicates(final IXtextGeneratorFileSystemAccess fsa, final TypeReference parser) {
final String content = fsa.readTextFile(parser.getJavaPath()).toString();
UnorderedGroupsSplitter splitter = new UnorderedGroupsSplitter(content);
String transformed = splitter.transform();
SyntacticPredicateFixup fixup = new SyntacticPredicateFixup(transformed);
transformed = fixup.transform();
BacktrackingGuardForUnorderedGroupsRemover remover = new BacktrackingGuardForUnorderedGroupsRemover(transformed);
String newContent = remover.transform();
fsa.generateFile(parser.getJavaPath(), newContent);
}
protected void suppressWarnings(final IXtextGeneratorFileSystemAccess fsa, final TypeReference type) {
final String content = fsa.readTextFile(type.getJavaPath()).toString();
final String newContent = new SuppressWarningsProcessor().process(content);
fsa.generateFile(type.getJavaPath(), newContent);
}
protected void suppressWarnings(final IXtextGeneratorFileSystemAccess fsa, final TypeReference... types) {
final Consumer<TypeReference> _function = (TypeReference it) -> {
this.suppressWarnings(fsa, it);
};
((List<TypeReference>)Conversions.doWrapArray(types)).forEach(_function);
}
protected void normalizeLineDelimiters(final IXtextGeneratorFileSystemAccess fsa, final TypeReference type) {
String content = fsa.readTextFile(type.getJavaPath()).toString();
content = this.newLineNormalizer.postProcess(fsa.getURI(type.getJavaPath()), content).toString();
content = content.replaceAll("\"\\+(\\r)?\\n\\s+\"", "");
fsa.generateFile(type.getJavaPath(), content);
}
protected void normalizeLineDelimiters(final IXtextGeneratorFileSystemAccess fsa, final TypeReference... types) {
final Consumer<TypeReference> _function = (TypeReference it) -> {
this.normalizeLineDelimiters(fsa, it);
};
((List<TypeReference>)Conversions.doWrapArray(types)).forEach(_function);
}
protected void normalizeTokens(final IXtextGeneratorFileSystemAccess fsa, final String tokenFile) {
String content = fsa.readTextFile(tokenFile).toString();
content = this.newLineNormalizer.postProcess(fsa.getURI(tokenFile), content).toString();
final List<String> splitted = Strings.split(content, this.codeConfig.getLineDelimiter());
Collections.<String>sort(splitted);
String _concat = Strings.concat(this.codeConfig.getLineDelimiter(), splitted);
String _lineDelimiter = this.codeConfig.getLineDelimiter();
String _plus = (_concat + _lineDelimiter);
content = _plus;
fsa.generateFile(tokenFile, content);
}
protected void splitParserAndLexerIfEnabled(final IXtextGeneratorFileSystemAccess fsa, final TypeReference parser, final TypeReference lexer) {
this.improveCodeQuality(fsa, lexer, parser);
boolean _isClassSplitting = this.getOptions().isClassSplitting();
if (_isClassSplitting) {
this.splitLexerClassFile(fsa, lexer);
this.splitParserClassFile(fsa, parser);
}
}
protected void improveCodeQuality(final IXtextGeneratorFileSystemAccess fsa, final TypeReference lexer, final TypeReference parser) {
this.improveLexerCodeQuality(fsa, lexer);
this.improveParserCodeQuality(fsa, parser);
}
protected void improveParserCodeQuality(final IXtextGeneratorFileSystemAccess fsa, final TypeReference parser) {
String parserContent = fsa.readTextFile(parser.getJavaPath()).toString();
parserContent = this.codeQualityHelper.stripUnnecessaryComments(parserContent, this.options);
parserContent = this.codeQualityHelper.removeDuplicateBitsets(parserContent, this.options);
parserContent = this.codeQualityHelper.removeDuplicateDFAs(parserContent, this.options);
fsa.generateFile(parser.getJavaPath(), parserContent);
}
protected void improveLexerCodeQuality(final IXtextGeneratorFileSystemAccess fsa, final TypeReference lexer) {
String lexerContent = fsa.readTextFile(lexer.getJavaPath()).toString();
lexerContent = this.codeQualityHelper.stripUnnecessaryComments(lexerContent, this.options);
fsa.generateFile(lexer.getJavaPath(), lexerContent);
}
protected void cleanupLexerTokensFile(final AntlrGrammar lexerGrammar, final KeywordHelper helper, final IXtextGeneratorFileSystemAccess fsa) {
try {
boolean _isBacktrackLexer = this.options.isBacktrackLexer();
if (_isBacktrackLexer) {
final MutableTokenDefProvider provider = this.createLexerTokensProvider(lexerGrammar, helper, fsa);
final Iterator<Map.Entry<Integer, String>> entries = provider.getTokenDefMap().entrySet().iterator();
while (entries.hasNext()) {
{
final String value = entries.next().getValue();
if ((((!helper.isKeywordRule(value)) && (!value.startsWith("RULE_"))) && (!value.startsWith("SUPER_")))) {
entries.remove();
}
}
}
final CharArrayWriter writer = new CharArrayWriter();
PrintWriter _printWriter = new PrintWriter(writer);
provider.writeTokenFile(_printWriter);
String _tokensFileName = lexerGrammar.getTokensFileName();
char[] _charArray = writer.toCharArray();
String _string = new String(_charArray);
fsa.generateFile(_tokensFileName, _string);
}
} catch (Throwable _e) {
throw Exceptions.sneakyThrow(_e);
}
}
protected MutableTokenDefProvider createLexerTokensProvider(final AntlrGrammar lexerGrammar, final KeywordHelper helper, final IXtextGeneratorFileSystemAccess fsa) {
Charset _forName = Charset.forName(this.codeConfig.getEncoding());
final MutableTokenDefProvider provider = new MutableTokenDefProvider(helper, _forName);
final IAntlrTokenFileProvider _function = () -> {
return fsa.readBinaryFile(lexerGrammar.getTokensFileName());
};
provider.setAntlrTokenFileProvider(_function);
return provider;
}
protected void cleanupParserTokensFile(final AntlrGrammar lexerGrammar, final AntlrGrammar parserGrammar, final KeywordHelper helper, final IXtextGeneratorFileSystemAccess fsa) {
try {
final MutableTokenDefProvider provider = this.createLexerTokensProvider(lexerGrammar, helper, fsa);
Set<Map.Entry<Integer, String>> _entrySet = provider.getTokenDefMap().entrySet();
for (final Map.Entry<Integer, String> entry : _entrySet) {
{
final String value = entry.getValue();
boolean _isKeywordRule = helper.isKeywordRule(value);
if (_isKeywordRule) {
final String keywordAsAntlrString = AntlrGrammarGenUtil.toAntlrString(helper.getKeywordValue(value));
entry.setValue((("\'" + keywordAsAntlrString) + "\'"));
} else {
boolean _startsWith = value.startsWith("\'");
if (_startsWith) {
String _antlrString = AntlrGrammarGenUtil.toAntlrString(value);
String _plus = ("\'" + _antlrString);
String _plus_1 = (_plus + "\'");
entry.setValue(_plus_1);
}
}
}
}
final CharArrayWriter writer = new CharArrayWriter();
PrintWriter _printWriter = new PrintWriter(writer);
provider.writeTokenFile(_printWriter);
String _tokensFileName = parserGrammar.getTokensFileName();
char[] _charArray = writer.toCharArray();
String _string = new String(_charArray);
fsa.generateFile(_tokensFileName, _string);
} catch (Throwable _e) {
throw Exceptions.sneakyThrow(_e);
}
}
protected void removeBackTrackingGuards(final IXtextGeneratorFileSystemAccess fsa, final TypeReference parser, final int lookaheadThreshold) {
final String content = fsa.readTextFile(parser.getJavaPath()).toString();
final BacktrackingGuardRemover remover = new BacktrackingGuardRemover(content, lookaheadThreshold);
final String newContent = remover.transform();
fsa.generateFile(parser.getJavaPath(), newContent);
}
protected boolean containsUnorderedGroup(final Grammar grammar) {
List<ParserRule> _allParserRules = GrammarUtil.allParserRules(grammar);
for (final ParserRule rule : _allParserRules) {
boolean _hasNext = Iterators.<UnorderedGroup>filter(rule.eAllContents(), UnorderedGroup.class).hasNext();
if (_hasNext) {
return true;
}
}
return false;
}
@Pure
protected AntlrToolFacade getAntlrTool() {
return this.antlrTool;
}
@Pure
protected AntlrCodeQualityHelper getCodeQualityHelper() {
return this.codeQualityHelper;
}
@Pure
protected LineSeparatorHarmonizer getNewLineNormalizer() {
return this.newLineNormalizer;
}
@Pure
protected CodeConfig getCodeConfig() {
return this.codeConfig;
}
@Pure
public AntlrOptions getOptions() {
return this.options;
}
public void setOptions(final AntlrOptions options) {
this.options = options;
}
}

View file

@ -1,153 +0,0 @@
/**
* Copyright (c) 2015 itemis AG (http://www.itemis.eu) and others.
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0.
*
* SPDX-License-Identifier: EPL-2.0
*/
package org.eclipse.xtext.xtext.generator.parser.antlr;
import com.google.inject.Inject;
import com.google.inject.Singleton;
import org.eclipse.xtend2.lib.StringConcatenation;
import org.eclipse.xtext.Grammar;
import org.eclipse.xtext.GrammarUtil;
import org.eclipse.xtext.xbase.lib.Extension;
import org.eclipse.xtext.xtext.generator.XtextGeneratorNaming;
import org.eclipse.xtext.xtext.generator.model.TypeReference;
import org.eclipse.xtext.xtext.generator.parser.antlr.AntlrGrammar;
import org.eclipse.xtext.xtext.generator.parser.antlr.CombinedGrammarMarker;
@Singleton
@SuppressWarnings("all")
public class GrammarNaming {
@Inject
@Extension
private XtextGeneratorNaming _xtextGeneratorNaming;
public boolean isCombinedGrammar(final Grammar it) {
return CombinedGrammarMarker.findInEmfObject(it).isCombinedGrammar();
}
protected String getParserPackage(final Grammar it) {
String _runtimeBasePackage = this._xtextGeneratorNaming.getRuntimeBasePackage(it);
return (_runtimeBasePackage + ".parser.antlr");
}
protected String getInternalParserPackage(final Grammar it) {
String _parserPackage = this.getParserPackage(it);
return (_parserPackage + ".internal");
}
protected String getInternalLexerPackage(final Grammar it) {
String _parserPackage = this.getParserPackage(it);
return (_parserPackage + ".lexer");
}
public AntlrGrammar getParserGrammar(final Grammar it) {
String _internalParserPackage = this.getInternalParserPackage(it);
StringConcatenation _builder = new StringConcatenation();
String _grammarNamePrefix = this.getGrammarNamePrefix(it);
_builder.append(_grammarNamePrefix);
_builder.append("Internal");
String _simpleName = GrammarUtil.getSimpleName(it);
_builder.append(_simpleName);
{
boolean _isCombinedGrammar = this.isCombinedGrammar(it);
boolean _not = (!_isCombinedGrammar);
if (_not) {
_builder.append("Parser");
}
}
return new AntlrGrammar(_internalParserPackage, _builder.toString());
}
public AntlrGrammar getLexerGrammar(final Grammar it) {
AntlrGrammar _xifexpression = null;
boolean _isCombinedGrammar = this.isCombinedGrammar(it);
if (_isCombinedGrammar) {
_xifexpression = this.getParserGrammar(it);
} else {
String _internalLexerPackage = this.getInternalLexerPackage(it);
StringConcatenation _builder = new StringConcatenation();
String _grammarNamePrefix = this.getGrammarNamePrefix(it);
_builder.append(_grammarNamePrefix);
_builder.append("Internal");
String _simpleName = GrammarUtil.getSimpleName(it);
_builder.append(_simpleName);
_builder.append("Lexer");
_xifexpression = new AntlrGrammar(_internalLexerPackage, _builder.toString());
}
return _xifexpression;
}
protected String getGrammarNamePrefix(final Grammar it) {
return "";
}
public TypeReference getLexerClass(final Grammar it) {
String _packageName = this.getLexerGrammar(it).getPackageName();
StringConcatenation _builder = new StringConcatenation();
String _simpleName = this.getLexerGrammar(it).getSimpleName();
_builder.append(_simpleName);
{
boolean _isCombinedGrammar = this.isCombinedGrammar(it);
if (_isCombinedGrammar) {
_builder.append("Lexer");
}
}
return new TypeReference(_packageName, _builder.toString());
}
public TypeReference getLexerSuperClass(final Grammar it) {
return new TypeReference("org.eclipse.xtext.parser.antlr.Lexer");
}
public TypeReference getParserClass(final Grammar it) {
String _parserPackage = this.getParserPackage(it);
StringConcatenation _builder = new StringConcatenation();
String _simpleName = GrammarUtil.getSimpleName(it);
_builder.append(_simpleName);
_builder.append("Parser");
return new TypeReference(_parserPackage, _builder.toString());
}
public TypeReference getParserSuperClass(final Grammar it, final boolean partialParsing) {
return new TypeReference("org.eclipse.xtext.parser.antlr.AbstractAntlrParser");
}
public TypeReference getInternalParserClass(final Grammar it) {
String _packageName = this.getParserGrammar(it).getPackageName();
StringConcatenation _builder = new StringConcatenation();
String _simpleName = this.getParserGrammar(it).getSimpleName();
_builder.append(_simpleName);
{
boolean _isCombinedGrammar = this.isCombinedGrammar(it);
if (_isCombinedGrammar) {
_builder.append("Parser");
}
}
return new TypeReference(_packageName, _builder.toString());
}
public TypeReference getInternalParserSuperClass(final Grammar it) {
return new TypeReference("org.eclipse.xtext.parser.antlr.AbstractInternalAntlrParser");
}
public TypeReference getAntlrTokenFileProviderClass(final Grammar it) {
String _parserPackage = this.getParserPackage(it);
StringConcatenation _builder = new StringConcatenation();
String _simpleName = GrammarUtil.getSimpleName(it);
_builder.append(_simpleName);
_builder.append("AntlrTokenFileProvider");
return new TypeReference(_parserPackage, _builder.toString());
}
public TypeReference getTokenSourceClass(final Grammar it) {
String _parserPackage = this.getParserPackage(it);
String _simpleName = GrammarUtil.getSimpleName(it);
String _plus = (_simpleName + "TokenSource");
return new TypeReference(_parserPackage, _plus);
}
}