mirror of
https://github.com/sigmasternchen/xtext-core
synced 2025-03-15 08:18:55 +00:00
[eclipse/xtext#1679]ported more code to java
Signed-off-by: Christian Dietrich <christian.dietrich@itemis.de>
This commit is contained in:
parent
7e8ce132fb
commit
7b0d63dbd3
17 changed files with 608 additions and 1159 deletions
|
@ -0,0 +1,212 @@
|
|||
/**
|
||||
* Copyright (c) 2016, 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.editor.contentassist;
|
||||
|
||||
import org.eclipse.xtend2.lib.StringConcatenation;
|
||||
import org.eclipse.xtend2.lib.StringConcatenationClient;
|
||||
import org.eclipse.xtext.util.TextRegion;
|
||||
import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
|
||||
/**
|
||||
* Base class for adding template proposals from an {@link IdeContentProposalProvider} implementation. Use
|
||||
* {@link #variable(String)} and {@link #cursor()} to generate edit positions and an exit position into the proposal,
|
||||
* e.g.
|
||||
* <pre>
|
||||
* StringConcatenationClient template = new StringConcatenationClient() {
|
||||
* {@literal @}Override
|
||||
* protected void appendTo(StringConcatenationClient.TargetStringConcatenation target) {
|
||||
* target.append("state ");
|
||||
* target.append(variable("name"));
|
||||
* target.newLineIfNotEmpty();
|
||||
* target.append("\t");
|
||||
* target.append(cursor(), "\t");
|
||||
* target.newLineIfNotEmpty();
|
||||
* target.append("end");
|
||||
* target.newLine();
|
||||
* }
|
||||
* };
|
||||
* acceptProposal("state", "Create a new state", template, context, acceptor);
|
||||
* </pre>
|
||||
*
|
||||
* @since 2.10
|
||||
*/
|
||||
public abstract class AbstractIdeTemplateProposalProvider {
|
||||
/**
|
||||
* Placeholder for a variable (edit position) in a template.
|
||||
*/
|
||||
protected static class Variable {
|
||||
private final String name;
|
||||
|
||||
public Variable(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + ((name == null) ? 0 : name.hashCode());
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null)
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
Variable other = (Variable) obj;
|
||||
if (name == null) {
|
||||
if (other.name != null)
|
||||
return false;
|
||||
} else if (!name.equals(other.name))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
ToStringBuilder b = new ToStringBuilder(this);
|
||||
b.add("name", name);
|
||||
return b.toString();
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Placeholder for the cursor (exit position) in a template.
|
||||
*/
|
||||
protected static class Cursor {
|
||||
}
|
||||
|
||||
private static class TemplateStringConcatenation extends StringConcatenation {
|
||||
private final ContentAssistContext context;
|
||||
|
||||
private final ContentAssistEntry entry;
|
||||
|
||||
public TemplateStringConcatenation(ContentAssistContext context, ContentAssistEntry entry,
|
||||
String lineDelimiter) {
|
||||
super(lineDelimiter);
|
||||
this.context = context;
|
||||
this.entry = entry;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getStringRepresentation(Object object) {
|
||||
if (object instanceof Variable) {
|
||||
String varName = ((Variable) object).name;
|
||||
int offset = context.getReplaceRegion().getOffset() + getCurrentOffset();
|
||||
entry.getEditPositions().add(new TextRegion(offset, varName.length()));
|
||||
return varName;
|
||||
} else {
|
||||
if (object instanceof Cursor) {
|
||||
entry.setEscapePosition(
|
||||
Integer.valueOf(context.getReplaceRegion().getOffset() + getCurrentOffset()));
|
||||
return null;
|
||||
} else {
|
||||
return object.toString();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected int getCurrentOffset() {
|
||||
int result = 0;
|
||||
for (String segment : getContent()) {
|
||||
result = result + segment.length();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void newLineIfNotEmpty() {
|
||||
newLine();
|
||||
}
|
||||
}
|
||||
|
||||
@Inject
|
||||
private IdeContentProposalCreator proposalCreator;
|
||||
|
||||
@Inject
|
||||
private IdeContentProposalPriorities proposalPriorities;
|
||||
|
||||
protected Variable variable(String name) {
|
||||
return new Variable(name);
|
||||
}
|
||||
|
||||
protected Cursor cursor() {
|
||||
return new Cursor();
|
||||
}
|
||||
|
||||
protected void acceptProposal(String name, String description, StringConcatenationClient template,
|
||||
ContentAssistContext context, IIdeContentProposalAcceptor acceptor) {
|
||||
acceptProposal(name, description, template, context, acceptor, true);
|
||||
}
|
||||
|
||||
protected void acceptProposal(String name, String description, StringConcatenationClient template,
|
||||
ContentAssistContext context, IIdeContentProposalAcceptor acceptor, boolean adaptIndentation) {
|
||||
ContentAssistEntry entry = createProposal(template, context, adaptIndentation);
|
||||
if (canAcceptProposal(entry, context)) {
|
||||
entry.setLabel(name);
|
||||
entry.setDescription(description);
|
||||
acceptor.accept(entry, proposalPriorities.getDefaultPriority(entry));
|
||||
}
|
||||
}
|
||||
|
||||
protected boolean canAcceptProposal(ContentAssistEntry entry, ContentAssistContext context) {
|
||||
return proposalCreator.isValidProposal(entry.getProposal(), entry.getPrefix(), context);
|
||||
}
|
||||
|
||||
protected ContentAssistEntry createProposal(StringConcatenationClient template, ContentAssistContext context,
|
||||
boolean adaptIndentation) {
|
||||
ContentAssistEntry entry = new ContentAssistEntry();
|
||||
entry.setPrefix(context.getPrefix());
|
||||
TemplateStringConcatenation stringConcat = new TemplateStringConcatenation(context, entry, getLineDelimiter());
|
||||
String indentation = null;
|
||||
if (adaptIndentation) {
|
||||
indentation = getIndentation(context);
|
||||
}
|
||||
if (indentation == null) {
|
||||
stringConcat.append(template);
|
||||
} else {
|
||||
stringConcat.append(template, indentation);
|
||||
}
|
||||
entry.setProposal(stringConcat.toString());
|
||||
return entry;
|
||||
}
|
||||
|
||||
protected String getLineDelimiter() {
|
||||
return StringConcatenation.DEFAULT_LINE_DELIMITER;
|
||||
}
|
||||
|
||||
protected String getIndentation(ContentAssistContext context) {
|
||||
String text = null;
|
||||
if (context.getRootNode() != null) {
|
||||
text = context.getRootNode().getText();
|
||||
}
|
||||
if (text != null && text.length() >= context.getOffset()) {
|
||||
int lineStart = context.getReplaceRegion().getOffset();
|
||||
int indentEnd = lineStart;
|
||||
while (lineStart > 0 && text.charAt(lineStart - 1) != '\n') {
|
||||
lineStart--;
|
||||
if (!Character.isWhitespace(text.charAt(lineStart))) {
|
||||
indentEnd = lineStart;
|
||||
}
|
||||
}
|
||||
return text.substring(lineStart, indentEnd);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
|
@ -1,147 +0,0 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2016 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.editor.contentassist
|
||||
|
||||
import com.google.inject.Inject
|
||||
import org.eclipse.xtend.lib.annotations.Data
|
||||
import org.eclipse.xtend2.lib.StringConcatenation
|
||||
import org.eclipse.xtend2.lib.StringConcatenationClient
|
||||
import org.eclipse.xtext.util.TextRegion
|
||||
|
||||
/**
|
||||
* Base class for adding template proposals from an {@link IdeContentProposalProvider} implementation.
|
||||
* Use {@link #variable(String)} and {@link #cursor()} to generate edit positions and an exit position
|
||||
* into the proposal, e.g.
|
||||
* <pre>
|
||||
* val StringConcatenationClient template = '''
|
||||
* state «variable('name')»
|
||||
* «cursor»
|
||||
* end
|
||||
* '''
|
||||
* acceptProposal('state', 'Create a new state', template, context, acceptor)
|
||||
* </pre>
|
||||
*
|
||||
* @since 2.10
|
||||
*/
|
||||
abstract class AbstractIdeTemplateProposalProvider {
|
||||
|
||||
@Inject IdeContentProposalCreator proposalCreator
|
||||
|
||||
@Inject IdeContentProposalPriorities proposalPriorities
|
||||
|
||||
/** Placeholder for a variable (edit position) in a template. */
|
||||
@Data
|
||||
protected static class Variable {
|
||||
String name
|
||||
}
|
||||
|
||||
protected def Variable variable(String name) {
|
||||
new Variable(name)
|
||||
}
|
||||
|
||||
/** Placeholder for the cursor (exit position) in a template. */
|
||||
protected static class Cursor {
|
||||
}
|
||||
|
||||
protected def Cursor cursor() {
|
||||
new Cursor
|
||||
}
|
||||
|
||||
protected def void acceptProposal(String name, String description, StringConcatenationClient template,
|
||||
ContentAssistContext context, IIdeContentProposalAcceptor acceptor) {
|
||||
acceptProposal(name, description, template, context, acceptor, true)
|
||||
}
|
||||
|
||||
protected def void acceptProposal(String name, String description, StringConcatenationClient template,
|
||||
ContentAssistContext context, IIdeContentProposalAcceptor acceptor, boolean adaptIndentation) {
|
||||
val entry = createProposal(template, context, adaptIndentation)
|
||||
if (canAcceptProposal(entry, context)) {
|
||||
entry.label = name
|
||||
entry.description = description
|
||||
acceptor.accept(entry, proposalPriorities.getDefaultPriority(entry))
|
||||
}
|
||||
}
|
||||
|
||||
protected def boolean canAcceptProposal(ContentAssistEntry entry, ContentAssistContext context) {
|
||||
proposalCreator.isValidProposal(entry.proposal, entry.prefix, context)
|
||||
}
|
||||
|
||||
protected def ContentAssistEntry createProposal(StringConcatenationClient template,
|
||||
ContentAssistContext context, boolean adaptIndentation) {
|
||||
val entry = new ContentAssistEntry
|
||||
entry.prefix = context.prefix
|
||||
val stringConcat = new TemplateStringConcatenation(context, entry, lineDelimiter)
|
||||
val indentation = if (adaptIndentation) context.indentation else null
|
||||
if (indentation === null)
|
||||
stringConcat.append(template)
|
||||
else
|
||||
stringConcat.append(template, indentation)
|
||||
entry.proposal = stringConcat.toString
|
||||
return entry
|
||||
}
|
||||
|
||||
protected def String getLineDelimiter() {
|
||||
StringConcatenation.DEFAULT_LINE_DELIMITER
|
||||
}
|
||||
|
||||
protected def String getIndentation(ContentAssistContext context) {
|
||||
val text = context.rootNode?.text
|
||||
if (text !== null && text.length >= context.offset) {
|
||||
var lineStart = context.replaceRegion.offset
|
||||
var indentEnd = lineStart
|
||||
while (lineStart > 0 && text.charAt(lineStart - 1) != '\n'.charAt(0)) {
|
||||
lineStart--
|
||||
if (!Character.isWhitespace(text.charAt(lineStart)))
|
||||
indentEnd = lineStart
|
||||
}
|
||||
return text.substring(lineStart, indentEnd)
|
||||
}
|
||||
}
|
||||
|
||||
private static class TemplateStringConcatenation extends StringConcatenation {
|
||||
|
||||
val ContentAssistContext context
|
||||
val ContentAssistEntry entry
|
||||
|
||||
new(ContentAssistContext context, ContentAssistEntry entry, String lineDelimiter) {
|
||||
super(lineDelimiter)
|
||||
this.context = context
|
||||
this.entry = entry
|
||||
}
|
||||
|
||||
override protected getStringRepresentation(Object object) {
|
||||
if (object instanceof Variable) {
|
||||
val varName = object.name
|
||||
val offset = context.replaceRegion.offset + currentOffset
|
||||
entry.editPositions.add(new TextRegion(offset, varName.length))
|
||||
return varName
|
||||
} else if (object instanceof Cursor) {
|
||||
val offset = context.replaceRegion.offset + currentOffset
|
||||
entry.setEscapePosition(offset)
|
||||
return null
|
||||
} else {
|
||||
return object.toString
|
||||
}
|
||||
}
|
||||
|
||||
protected def int getCurrentOffset() {
|
||||
var result = 0
|
||||
for (segment : content) {
|
||||
result += segment.length
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
override newLineIfNotEmpty() {
|
||||
newLine()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,158 @@
|
|||
/**
|
||||
* 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.server;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.io.PrintStream;
|
||||
import java.io.PrintWriter;
|
||||
import java.util.concurrent.Future;
|
||||
|
||||
import org.eclipse.lsp4j.jsonrpc.Launcher;
|
||||
import org.eclipse.lsp4j.services.LanguageClient;
|
||||
import org.eclipse.xtext.xbase.lib.Exceptions;
|
||||
import org.eclipse.xtext.xbase.lib.InputOutput;
|
||||
|
||||
import com.google.common.base.Objects;
|
||||
import com.google.common.io.ByteStreams;
|
||||
import com.google.inject.Guice;
|
||||
import com.google.inject.Inject;
|
||||
|
||||
/**
|
||||
* @author Sven Efftinge - Initial contribution and API
|
||||
* @since 2.11
|
||||
*/
|
||||
public class ServerLauncher {
|
||||
public static final String LOG = "-log";
|
||||
|
||||
public static final String TRACE = "-trace";
|
||||
|
||||
public static final String NO_VALIDATE = "-noValidate";
|
||||
|
||||
public static void main(String[] args) {
|
||||
launch(ServerLauncher.class.getName(), args, new ServerModule());
|
||||
}
|
||||
|
||||
public static void launch(String prefix, String[] args, com.google.inject.Module... modules) {
|
||||
LaunchArgs launchArgs = createLaunchArgs(prefix, args);
|
||||
ServerLauncher launcher = Guice.createInjector(modules).<ServerLauncher>getInstance(ServerLauncher.class);
|
||||
launcher.start(launchArgs);
|
||||
}
|
||||
|
||||
@Inject
|
||||
private LanguageServerImpl languageServer;
|
||||
|
||||
public void start(LaunchArgs args) {
|
||||
try {
|
||||
InputOutput.println("Xtext Language Server is starting.");
|
||||
Launcher<LanguageClient> launcher = Launcher.createLauncher(languageServer,
|
||||
LanguageClient.class, args.getIn(), args.getOut(), args.isValidate(), args.getTrace());
|
||||
languageServer.connect(launcher.getRemoteProxy());
|
||||
Future<Void> future = launcher.startListening();
|
||||
InputOutput.println("Xtext Language Server has been started.");
|
||||
while (!future.isDone()) {
|
||||
Thread.sleep(10_000L);
|
||||
}
|
||||
} catch (InterruptedException e) {
|
||||
throw Exceptions.sneakyThrow(e);
|
||||
}
|
||||
}
|
||||
|
||||
public static LaunchArgs createLaunchArgs(String prefix, String[] args) {
|
||||
LaunchArgs launchArgs = new LaunchArgs();
|
||||
launchArgs.setIn(System.in);
|
||||
launchArgs.setOut(System.out);
|
||||
redirectStandardStreams(prefix, args);
|
||||
launchArgs.setTrace(getTrace(args));
|
||||
launchArgs.setValidate(shouldValidate(args));
|
||||
return launchArgs;
|
||||
}
|
||||
|
||||
public static PrintWriter getTrace(String[] args) {
|
||||
if (shouldTrace(args)) {
|
||||
return createTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static PrintWriter createTrace() {
|
||||
return new PrintWriter(System.out);
|
||||
}
|
||||
|
||||
public static void redirectStandardStreams(String prefix, String[] args) {
|
||||
if (shouldLogStandardStreams(args)) {
|
||||
logStandardStreams(prefix);
|
||||
} else {
|
||||
silentStandardStreams();
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean shouldValidate(String[] args) {
|
||||
return !testArg(args, ServerLauncher.NO_VALIDATE);
|
||||
}
|
||||
|
||||
public static boolean shouldTrace(String[] args) {
|
||||
return testArg(args, ServerLauncher.TRACE);
|
||||
}
|
||||
|
||||
public static boolean shouldLogStandardStreams(String[] args) {
|
||||
return testArg(args, ServerLauncher.LOG, "debug");
|
||||
}
|
||||
|
||||
public static boolean testArg(String[] args, String... values) {
|
||||
for (String arg : args) {
|
||||
if (testArg(arg, values)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static boolean testArg(String arg, String... values) {
|
||||
for(String value : values) {
|
||||
if (Objects.equal(value, arg)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static void logStandardStreams(String prefix) {
|
||||
try {
|
||||
FileOutputStream stdFileOut = new FileOutputStream(prefix + "-debug.log");
|
||||
redirectStandardStreams(stdFileOut);
|
||||
} catch (IOException e) {
|
||||
throw Exceptions.sneakyThrow(e);
|
||||
}
|
||||
}
|
||||
|
||||
public static void silentStandardStreams() {
|
||||
redirectStandardStreams(silentOut());
|
||||
}
|
||||
|
||||
public static void redirectStandardStreams(OutputStream out) {
|
||||
redirectStandardStreams(silentIn(), out);
|
||||
}
|
||||
|
||||
public static void redirectStandardStreams(InputStream in, OutputStream out) {
|
||||
System.setIn(in);
|
||||
System.setOut(new PrintStream(out));
|
||||
}
|
||||
|
||||
public static OutputStream silentOut() {
|
||||
return ByteStreams.nullOutputStream();
|
||||
}
|
||||
|
||||
public static InputStream silentIn() {
|
||||
return new ByteArrayInputStream(new byte[0]);
|
||||
}
|
||||
}
|
|
@ -1,131 +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.server
|
||||
|
||||
import com.google.common.io.ByteStreams
|
||||
import com.google.inject.Guice
|
||||
import com.google.inject.Inject
|
||||
import com.google.inject.Module
|
||||
import java.io.ByteArrayInputStream
|
||||
import java.io.FileOutputStream
|
||||
import java.io.InputStream
|
||||
import java.io.OutputStream
|
||||
import java.io.PrintStream
|
||||
import java.io.PrintWriter
|
||||
import org.eclipse.lsp4j.jsonrpc.Launcher
|
||||
import org.eclipse.lsp4j.services.LanguageClient
|
||||
|
||||
/**
|
||||
* @author Sven Efftinge - Initial contribution and API
|
||||
* @since 2.11
|
||||
*/
|
||||
class ServerLauncher {
|
||||
|
||||
public static val LOG = '-log'
|
||||
public static val TRACE = '-trace'
|
||||
public static val NO_VALIDATE = '-noValidate'
|
||||
|
||||
def static void main(String[] args) {
|
||||
launch(ServerLauncher.name, args, new ServerModule)
|
||||
}
|
||||
|
||||
def static void launch(String prefix, String[] args, Module... modules) {
|
||||
val launchArgs = createLaunchArgs(prefix, args)
|
||||
|
||||
val launcher = Guice.createInjector(modules).getInstance(ServerLauncher)
|
||||
launcher.start(launchArgs)
|
||||
}
|
||||
|
||||
@Inject LanguageServerImpl languageServer
|
||||
|
||||
def void start(LaunchArgs it) {
|
||||
println("Xtext Language Server is starting.")
|
||||
val launcher = Launcher.createLauncher(languageServer, LanguageClient, in, out, validate, trace)
|
||||
languageServer.connect(launcher.remoteProxy)
|
||||
val future = launcher.startListening
|
||||
println("Xtext Language Server has been started.")
|
||||
while (!future.done) {
|
||||
Thread.sleep(10_000l)
|
||||
}
|
||||
}
|
||||
|
||||
def static LaunchArgs createLaunchArgs(String prefix, String[] args) {
|
||||
val launchArgs = new LaunchArgs
|
||||
launchArgs.in = System.in
|
||||
launchArgs.out = System.out
|
||||
redirectStandardStreams(prefix, args)
|
||||
launchArgs.trace = args.trace
|
||||
launchArgs.validate = args.shouldValidate
|
||||
return launchArgs
|
||||
}
|
||||
|
||||
def static PrintWriter getTrace(String[] args) {
|
||||
if (shouldTrace(args))
|
||||
return createTrace
|
||||
}
|
||||
|
||||
def static PrintWriter createTrace() {
|
||||
return new PrintWriter(System.out)
|
||||
}
|
||||
|
||||
def static redirectStandardStreams(String prefix, String[] args) {
|
||||
if (shouldLogStandardStreams(args)) {
|
||||
logStandardStreams(prefix)
|
||||
} else {
|
||||
silentStandardStreams
|
||||
}
|
||||
}
|
||||
|
||||
def static boolean shouldValidate(String[] args) {
|
||||
return !args.testArg(NO_VALIDATE)
|
||||
}
|
||||
|
||||
def static boolean shouldTrace(String[] args) {
|
||||
return args.testArg(TRACE)
|
||||
}
|
||||
|
||||
def static boolean shouldLogStandardStreams(String[] args) {
|
||||
return args.testArg(ServerLauncher.LOG, 'debug')
|
||||
}
|
||||
|
||||
def static boolean testArg(String[] args, String ... values) {
|
||||
return args.exists[arg|arg.testArg(values)]
|
||||
}
|
||||
|
||||
def static boolean testArg(String arg, String ... values) {
|
||||
return values.exists[value|value == arg]
|
||||
}
|
||||
|
||||
def static void logStandardStreams(String prefix) {
|
||||
val stdFileOut = new FileOutputStream(prefix + "-debug.log")
|
||||
redirectStandardStreams(stdFileOut)
|
||||
}
|
||||
|
||||
def static void silentStandardStreams() {
|
||||
redirectStandardStreams(ServerLauncher.silentOut)
|
||||
}
|
||||
|
||||
def static void redirectStandardStreams(OutputStream out) {
|
||||
redirectStandardStreams(ServerLauncher.silentIn, out)
|
||||
}
|
||||
|
||||
def static void redirectStandardStreams(InputStream in, OutputStream out) {
|
||||
System.setIn(in)
|
||||
System.setOut(new PrintStream(out))
|
||||
}
|
||||
|
||||
def static OutputStream silentOut() {
|
||||
ByteStreams.nullOutputStream
|
||||
}
|
||||
|
||||
def static InputStream silentIn() {
|
||||
new ByteArrayInputStream(newByteArrayOfSize(0))
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,125 @@
|
|||
/**
|
||||
* Copyright (c) 2019, 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.server;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.io.PrintWriter;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.nio.channels.AsynchronousServerSocketChannel;
|
||||
import java.nio.channels.AsynchronousSocketChannel;
|
||||
import java.nio.channels.Channels;
|
||||
|
||||
import org.apache.log4j.Logger;
|
||||
import org.eclipse.lsp4j.jsonrpc.Launcher;
|
||||
import org.eclipse.lsp4j.services.LanguageClient;
|
||||
import org.eclipse.xtext.xbase.lib.ArrayExtensions;
|
||||
|
||||
import com.google.common.base.Objects;
|
||||
import com.google.inject.Guice;
|
||||
import com.google.inject.Injector;
|
||||
|
||||
/**
|
||||
* Allows to launch a language server via a server socket.
|
||||
*
|
||||
* Useful for debugging live language servers.
|
||||
*
|
||||
* @author Jan Köhnlein - Initial contribution and API
|
||||
* @since 2.18
|
||||
*/
|
||||
public class SocketServerLauncher {
|
||||
|
||||
private static final Logger LOG = Logger.getLogger(SocketServerLauncher.class);
|
||||
public static final String HOST = "-host";
|
||||
|
||||
public static final String PORT = "-port";
|
||||
|
||||
public static final String TRACE = "-trace";
|
||||
|
||||
public static final String NO_VALIDATE = "-noValidate";
|
||||
|
||||
public static final int DEFAULT_PORT = 5008;
|
||||
|
||||
public static final String DEFAULT_HOST = "0.0.0.0";
|
||||
|
||||
public static void main(String[] args) {
|
||||
new SocketServerLauncher().launch(args);
|
||||
}
|
||||
|
||||
public void launch(String[] args) {
|
||||
Injector injector = Guice.createInjector(getServerModule());
|
||||
try (AsynchronousServerSocketChannel serverSocket = AsynchronousServerSocketChannel.open()
|
||||
.bind(getSocketAddress(args))) {
|
||||
LOG.info("Started server socket at " + getSocketAddress(args));
|
||||
while (true) {
|
||||
AsynchronousSocketChannel socketChannel = serverSocket.accept().get();
|
||||
InputStream in = Channels.newInputStream(socketChannel);
|
||||
OutputStream out = Channels.newOutputStream(socketChannel);
|
||||
PrintWriter trace = getTrace(args);
|
||||
boolean validate = shouldValidate(args);
|
||||
LanguageServerImpl languageServer = injector.getInstance(LanguageServerImpl.class);
|
||||
LOG
|
||||
.info("Starting Xtext Language Server for client " + socketChannel.getRemoteAddress());
|
||||
Launcher<LanguageClient> launcher = Launcher.createLauncher(languageServer, LanguageClient.class, in,
|
||||
out, validate, trace);
|
||||
languageServer.connect(launcher.getRemoteProxy());
|
||||
launcher.startListening();
|
||||
LOG.info("Xtext Language Server has been started.");
|
||||
}
|
||||
} catch (Throwable t) {
|
||||
t.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
protected com.google.inject.Module getServerModule() {
|
||||
return new ServerModule();
|
||||
}
|
||||
|
||||
protected PrintWriter getTrace(String... args) {
|
||||
if (ArrayExtensions.contains(args, TRACE)) {
|
||||
return new PrintWriter(System.out);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
protected boolean shouldValidate(String... args) {
|
||||
return !ArrayExtensions.contains(args, NO_VALIDATE);
|
||||
}
|
||||
|
||||
protected InetSocketAddress getSocketAddress(String... args) {
|
||||
return new InetSocketAddress(getHost(args), getPort(args));
|
||||
}
|
||||
|
||||
protected String getHost(String... args) {
|
||||
String host = getValue(args, HOST);
|
||||
if (host != null) {
|
||||
return host;
|
||||
} else {
|
||||
return DEFAULT_HOST;
|
||||
}
|
||||
}
|
||||
|
||||
protected int getPort(String... args) {
|
||||
Integer port = Integer.getInteger(getValue(args, PORT));
|
||||
if (port != null) {
|
||||
return port;
|
||||
} else {
|
||||
return DEFAULT_PORT;
|
||||
}
|
||||
}
|
||||
|
||||
protected String getValue(String[] args, String argName) {
|
||||
for (int i = 0; (i < (args.length - 1)); i++) {
|
||||
if (Objects.equal(args[i], argName)) {
|
||||
return args[i + 1];
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
|
@ -1,102 +0,0 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2019 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.server
|
||||
|
||||
import com.google.inject.Guice
|
||||
import java.io.PrintWriter
|
||||
import java.net.InetSocketAddress
|
||||
import java.nio.channels.AsynchronousServerSocketChannel
|
||||
import java.nio.channels.Channels
|
||||
import org.eclipse.lsp4j.jsonrpc.Launcher
|
||||
import org.eclipse.lsp4j.services.LanguageClient
|
||||
import org.eclipse.xtext.ide.server.LanguageServerImpl
|
||||
import org.eclipse.xtext.ide.server.ServerModule
|
||||
import org.eclipse.xtext.util.internal.Log
|
||||
import com.google.inject.Module
|
||||
|
||||
/**
|
||||
* Allows to launch a language server vie a server socket.
|
||||
*
|
||||
* Useful for debugging live language servers.
|
||||
*
|
||||
* @author Jan Köhnlein - Initial contribution and API
|
||||
* @since 2.18
|
||||
*/
|
||||
@Log
|
||||
class SocketServerLauncher {
|
||||
|
||||
public static val HOST = '-host'
|
||||
public static val PORT = '-port'
|
||||
public static val TRACE = '-trace'
|
||||
public static val NO_VALIDATE = '-noValidate'
|
||||
|
||||
public static val DEFAULT_PORT = 5008
|
||||
public static val DEFAULT_HOST = '0.0.0.0'
|
||||
|
||||
def static void main(String[] args) {
|
||||
new SocketServerLauncher().launch(args)
|
||||
}
|
||||
|
||||
def void launch(String[] args) {
|
||||
try {
|
||||
val injector = Guice.createInjector(serverModule)
|
||||
val serverSocket = AsynchronousServerSocketChannel.open.bind(args.socketAddress)
|
||||
LOG.info("Started server socket at " + args.socketAddress)
|
||||
while (true) {
|
||||
val socketChannel = serverSocket.accept.get
|
||||
val in = Channels.newInputStream(socketChannel)
|
||||
val out = Channels.newOutputStream(socketChannel)
|
||||
val trace = args.trace
|
||||
val validate = args.shouldValidate
|
||||
val languageServer = injector.getInstance(LanguageServerImpl)
|
||||
LOG.info("Starting Xtext Language Server for client " + socketChannel.remoteAddress)
|
||||
val launcher = Launcher.createLauncher(languageServer, LanguageClient, in, out, validate, trace)
|
||||
languageServer.connect(launcher.remoteProxy)
|
||||
launcher.startListening
|
||||
LOG.info("Xtext Language Server has been started.")
|
||||
}
|
||||
} catch (Throwable throwable) {
|
||||
throwable.printStackTrace()
|
||||
}
|
||||
}
|
||||
|
||||
protected def Module getServerModule() {
|
||||
new ServerModule
|
||||
}
|
||||
|
||||
protected def PrintWriter getTrace(String... args) {
|
||||
if (args.contains(TRACE))
|
||||
new PrintWriter(System.out)
|
||||
}
|
||||
|
||||
protected def boolean shouldValidate(String... args) {
|
||||
!args.contains(NO_VALIDATE)
|
||||
}
|
||||
|
||||
protected def InetSocketAddress getSocketAddress(String... args) {
|
||||
new InetSocketAddress(args.host, args.port)
|
||||
}
|
||||
|
||||
protected def String getHost(String... args) {
|
||||
args.getValue(HOST) ?: DEFAULT_HOST
|
||||
}
|
||||
|
||||
protected def int getPort(String... args) {
|
||||
Integer.getInteger(args.getValue(PORT)) ?: DEFAULT_PORT
|
||||
}
|
||||
|
||||
protected def String getValue(String[] args, String argName) {
|
||||
for (var i = 0; i < args.length - 1; i++) {
|
||||
if (args.get(i) == argName)
|
||||
return args.get(i + 1)
|
||||
}
|
||||
return null
|
||||
}
|
||||
}
|
|
@ -1,233 +0,0 @@
|
|||
/**
|
||||
* Copyright (c) 2016 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.editor.contentassist;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import java.util.List;
|
||||
import org.eclipse.xtend.lib.annotations.Data;
|
||||
import org.eclipse.xtend2.lib.StringConcatenation;
|
||||
import org.eclipse.xtend2.lib.StringConcatenationClient;
|
||||
import org.eclipse.xtext.ide.editor.contentassist.ContentAssistContext;
|
||||
import org.eclipse.xtext.ide.editor.contentassist.ContentAssistEntry;
|
||||
import org.eclipse.xtext.ide.editor.contentassist.IIdeContentProposalAcceptor;
|
||||
import org.eclipse.xtext.ide.editor.contentassist.IdeContentProposalCreator;
|
||||
import org.eclipse.xtext.ide.editor.contentassist.IdeContentProposalPriorities;
|
||||
import org.eclipse.xtext.nodemodel.ICompositeNode;
|
||||
import org.eclipse.xtext.util.TextRegion;
|
||||
import org.eclipse.xtext.xbase.lib.Pure;
|
||||
import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
|
||||
|
||||
/**
|
||||
* Base class for adding template proposals from an {@link IdeContentProposalProvider} implementation.
|
||||
* Use {@link #variable(String)} and {@link #cursor()} to generate edit positions and an exit position
|
||||
* into the proposal, e.g.
|
||||
* <pre>
|
||||
* val StringConcatenationClient template = '''
|
||||
* state «variable('name')»
|
||||
* «cursor»
|
||||
* end
|
||||
* '''
|
||||
* acceptProposal('state', 'Create a new state', template, context, acceptor)
|
||||
* </pre>
|
||||
*
|
||||
* @since 2.10
|
||||
*/
|
||||
@SuppressWarnings("all")
|
||||
public abstract class AbstractIdeTemplateProposalProvider {
|
||||
/**
|
||||
* Placeholder for a variable (edit position) in a template.
|
||||
*/
|
||||
@Data
|
||||
protected static class Variable {
|
||||
private final String name;
|
||||
|
||||
public Variable(final String name) {
|
||||
super();
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Pure
|
||||
public int hashCode() {
|
||||
return 31 * 1 + ((this.name== null) ? 0 : this.name.hashCode());
|
||||
}
|
||||
|
||||
@Override
|
||||
@Pure
|
||||
public boolean equals(final Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null)
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
AbstractIdeTemplateProposalProvider.Variable other = (AbstractIdeTemplateProposalProvider.Variable) obj;
|
||||
if (this.name == null) {
|
||||
if (other.name != null)
|
||||
return false;
|
||||
} else if (!this.name.equals(other.name))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Pure
|
||||
public String toString() {
|
||||
ToStringBuilder b = new ToStringBuilder(this);
|
||||
b.add("name", this.name);
|
||||
return b.toString();
|
||||
}
|
||||
|
||||
@Pure
|
||||
public String getName() {
|
||||
return this.name;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Placeholder for the cursor (exit position) in a template.
|
||||
*/
|
||||
protected static class Cursor {
|
||||
}
|
||||
|
||||
private static class TemplateStringConcatenation extends StringConcatenation {
|
||||
private final ContentAssistContext context;
|
||||
|
||||
private final ContentAssistEntry entry;
|
||||
|
||||
public TemplateStringConcatenation(final ContentAssistContext context, final ContentAssistEntry entry, final String lineDelimiter) {
|
||||
super(lineDelimiter);
|
||||
this.context = context;
|
||||
this.entry = entry;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getStringRepresentation(final Object object) {
|
||||
if ((object instanceof AbstractIdeTemplateProposalProvider.Variable)) {
|
||||
final String varName = ((AbstractIdeTemplateProposalProvider.Variable)object).name;
|
||||
int _offset = this.context.getReplaceRegion().getOffset();
|
||||
int _currentOffset = this.getCurrentOffset();
|
||||
final int offset = (_offset + _currentOffset);
|
||||
List<TextRegion> _editPositions = this.entry.getEditPositions();
|
||||
int _length = varName.length();
|
||||
TextRegion _textRegion = new TextRegion(offset, _length);
|
||||
_editPositions.add(_textRegion);
|
||||
return varName;
|
||||
} else {
|
||||
if ((object instanceof AbstractIdeTemplateProposalProvider.Cursor)) {
|
||||
int _offset_1 = this.context.getReplaceRegion().getOffset();
|
||||
int _currentOffset_1 = this.getCurrentOffset();
|
||||
final int offset_1 = (_offset_1 + _currentOffset_1);
|
||||
this.entry.setEscapePosition(Integer.valueOf(offset_1));
|
||||
return null;
|
||||
} else {
|
||||
return object.toString();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected int getCurrentOffset() {
|
||||
int result = 0;
|
||||
List<String> _content = this.getContent();
|
||||
for (final String segment : _content) {
|
||||
int _result = result;
|
||||
int _length = segment.length();
|
||||
result = (_result + _length);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void newLineIfNotEmpty() {
|
||||
this.newLine();
|
||||
}
|
||||
}
|
||||
|
||||
@Inject
|
||||
private IdeContentProposalCreator proposalCreator;
|
||||
|
||||
@Inject
|
||||
private IdeContentProposalPriorities proposalPriorities;
|
||||
|
||||
protected AbstractIdeTemplateProposalProvider.Variable variable(final String name) {
|
||||
return new AbstractIdeTemplateProposalProvider.Variable(name);
|
||||
}
|
||||
|
||||
protected AbstractIdeTemplateProposalProvider.Cursor cursor() {
|
||||
return new AbstractIdeTemplateProposalProvider.Cursor();
|
||||
}
|
||||
|
||||
protected void acceptProposal(final String name, final String description, final StringConcatenationClient template, final ContentAssistContext context, final IIdeContentProposalAcceptor acceptor) {
|
||||
this.acceptProposal(name, description, template, context, acceptor, true);
|
||||
}
|
||||
|
||||
protected void acceptProposal(final String name, final String description, final StringConcatenationClient template, final ContentAssistContext context, final IIdeContentProposalAcceptor acceptor, final boolean adaptIndentation) {
|
||||
final ContentAssistEntry entry = this.createProposal(template, context, adaptIndentation);
|
||||
boolean _canAcceptProposal = this.canAcceptProposal(entry, context);
|
||||
if (_canAcceptProposal) {
|
||||
entry.setLabel(name);
|
||||
entry.setDescription(description);
|
||||
acceptor.accept(entry, this.proposalPriorities.getDefaultPriority(entry));
|
||||
}
|
||||
}
|
||||
|
||||
protected boolean canAcceptProposal(final ContentAssistEntry entry, final ContentAssistContext context) {
|
||||
return this.proposalCreator.isValidProposal(entry.getProposal(), entry.getPrefix(), context);
|
||||
}
|
||||
|
||||
protected ContentAssistEntry createProposal(final StringConcatenationClient template, final ContentAssistContext context, final boolean adaptIndentation) {
|
||||
final ContentAssistEntry entry = new ContentAssistEntry();
|
||||
entry.setPrefix(context.getPrefix());
|
||||
String _lineDelimiter = this.getLineDelimiter();
|
||||
final AbstractIdeTemplateProposalProvider.TemplateStringConcatenation stringConcat = new AbstractIdeTemplateProposalProvider.TemplateStringConcatenation(context, entry, _lineDelimiter);
|
||||
String _xifexpression = null;
|
||||
if (adaptIndentation) {
|
||||
_xifexpression = this.getIndentation(context);
|
||||
} else {
|
||||
_xifexpression = null;
|
||||
}
|
||||
final String indentation = _xifexpression;
|
||||
if ((indentation == null)) {
|
||||
stringConcat.append(template);
|
||||
} else {
|
||||
stringConcat.append(template, indentation);
|
||||
}
|
||||
entry.setProposal(stringConcat.toString());
|
||||
return entry;
|
||||
}
|
||||
|
||||
protected String getLineDelimiter() {
|
||||
return StringConcatenation.DEFAULT_LINE_DELIMITER;
|
||||
}
|
||||
|
||||
protected String getIndentation(final ContentAssistContext context) {
|
||||
ICompositeNode _rootNode = context.getRootNode();
|
||||
String _text = null;
|
||||
if (_rootNode!=null) {
|
||||
_text=_rootNode.getText();
|
||||
}
|
||||
final String text = _text;
|
||||
if (((text != null) && (text.length() >= context.getOffset()))) {
|
||||
int lineStart = context.getReplaceRegion().getOffset();
|
||||
int indentEnd = lineStart;
|
||||
while (((lineStart > 0) && (text.charAt((lineStart - 1)) != "\n".charAt(0)))) {
|
||||
{
|
||||
lineStart--;
|
||||
boolean _isWhitespace = Character.isWhitespace(text.charAt(lineStart));
|
||||
boolean _not = (!_isWhitespace);
|
||||
if (_not) {
|
||||
indentEnd = lineStart;
|
||||
}
|
||||
}
|
||||
}
|
||||
return text.substring(lineStart, indentEnd);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
|
@ -1,164 +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.server;
|
||||
|
||||
import com.google.common.base.Objects;
|
||||
import com.google.common.io.ByteStreams;
|
||||
import com.google.inject.Guice;
|
||||
import com.google.inject.Inject;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.io.PrintStream;
|
||||
import java.io.PrintWriter;
|
||||
import java.util.concurrent.Future;
|
||||
import org.eclipse.lsp4j.jsonrpc.Launcher;
|
||||
import org.eclipse.lsp4j.services.LanguageClient;
|
||||
import org.eclipse.xtext.ide.server.LanguageServerImpl;
|
||||
import org.eclipse.xtext.ide.server.LaunchArgs;
|
||||
import org.eclipse.xtext.ide.server.ServerModule;
|
||||
import org.eclipse.xtext.xbase.lib.Conversions;
|
||||
import org.eclipse.xtext.xbase.lib.Exceptions;
|
||||
import org.eclipse.xtext.xbase.lib.Functions.Function1;
|
||||
import org.eclipse.xtext.xbase.lib.InputOutput;
|
||||
import org.eclipse.xtext.xbase.lib.IterableExtensions;
|
||||
|
||||
/**
|
||||
* @author Sven Efftinge - Initial contribution and API
|
||||
* @since 2.11
|
||||
*/
|
||||
@SuppressWarnings("all")
|
||||
public class ServerLauncher {
|
||||
public static final String LOG = "-log";
|
||||
|
||||
public static final String TRACE = "-trace";
|
||||
|
||||
public static final String NO_VALIDATE = "-noValidate";
|
||||
|
||||
public static void main(final String[] args) {
|
||||
String _name = ServerLauncher.class.getName();
|
||||
ServerModule _serverModule = new ServerModule();
|
||||
ServerLauncher.launch(_name, args, _serverModule);
|
||||
}
|
||||
|
||||
public static void launch(final String prefix, final String[] args, final com.google.inject.Module... modules) {
|
||||
final LaunchArgs launchArgs = ServerLauncher.createLaunchArgs(prefix, args);
|
||||
final ServerLauncher launcher = Guice.createInjector(modules).<ServerLauncher>getInstance(ServerLauncher.class);
|
||||
launcher.start(launchArgs);
|
||||
}
|
||||
|
||||
@Inject
|
||||
private LanguageServerImpl languageServer;
|
||||
|
||||
public void start(final LaunchArgs it) {
|
||||
try {
|
||||
InputOutput.<String>println("Xtext Language Server is starting.");
|
||||
final Launcher<LanguageClient> launcher = Launcher.<LanguageClient>createLauncher(this.languageServer, LanguageClient.class, it.getIn(), it.getOut(), it.isValidate(), it.getTrace());
|
||||
this.languageServer.connect(launcher.getRemoteProxy());
|
||||
final Future<Void> future = launcher.startListening();
|
||||
InputOutput.<String>println("Xtext Language Server has been started.");
|
||||
while ((!future.isDone())) {
|
||||
Thread.sleep(10_000l);
|
||||
}
|
||||
} catch (Throwable _e) {
|
||||
throw Exceptions.sneakyThrow(_e);
|
||||
}
|
||||
}
|
||||
|
||||
public static LaunchArgs createLaunchArgs(final String prefix, final String[] args) {
|
||||
final LaunchArgs launchArgs = new LaunchArgs();
|
||||
launchArgs.setIn(System.in);
|
||||
launchArgs.setOut(System.out);
|
||||
ServerLauncher.redirectStandardStreams(prefix, args);
|
||||
launchArgs.setTrace(ServerLauncher.getTrace(args));
|
||||
launchArgs.setValidate(ServerLauncher.shouldValidate(args));
|
||||
return launchArgs;
|
||||
}
|
||||
|
||||
public static PrintWriter getTrace(final String[] args) {
|
||||
boolean _shouldTrace = ServerLauncher.shouldTrace(args);
|
||||
if (_shouldTrace) {
|
||||
return ServerLauncher.createTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static PrintWriter createTrace() {
|
||||
return new PrintWriter(System.out);
|
||||
}
|
||||
|
||||
public static void redirectStandardStreams(final String prefix, final String[] args) {
|
||||
boolean _shouldLogStandardStreams = ServerLauncher.shouldLogStandardStreams(args);
|
||||
if (_shouldLogStandardStreams) {
|
||||
ServerLauncher.logStandardStreams(prefix);
|
||||
} else {
|
||||
ServerLauncher.silentStandardStreams();
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean shouldValidate(final String[] args) {
|
||||
boolean _testArg = ServerLauncher.testArg(args, ServerLauncher.NO_VALIDATE);
|
||||
return (!_testArg);
|
||||
}
|
||||
|
||||
public static boolean shouldTrace(final String[] args) {
|
||||
return ServerLauncher.testArg(args, ServerLauncher.TRACE);
|
||||
}
|
||||
|
||||
public static boolean shouldLogStandardStreams(final String[] args) {
|
||||
return ServerLauncher.testArg(args, ServerLauncher.LOG, "debug");
|
||||
}
|
||||
|
||||
public static boolean testArg(final String[] args, final String... values) {
|
||||
final Function1<String, Boolean> _function = (String arg) -> {
|
||||
return Boolean.valueOf(ServerLauncher.testArg(arg, values));
|
||||
};
|
||||
return IterableExtensions.<String>exists(((Iterable<String>)Conversions.doWrapArray(args)), _function);
|
||||
}
|
||||
|
||||
public static boolean testArg(final String arg, final String... values) {
|
||||
final Function1<String, Boolean> _function = (String value) -> {
|
||||
return Boolean.valueOf(Objects.equal(value, arg));
|
||||
};
|
||||
return IterableExtensions.<String>exists(((Iterable<String>)Conversions.doWrapArray(values)), _function);
|
||||
}
|
||||
|
||||
public static void logStandardStreams(final String prefix) {
|
||||
try {
|
||||
final FileOutputStream stdFileOut = new FileOutputStream((prefix + "-debug.log"));
|
||||
ServerLauncher.redirectStandardStreams(stdFileOut);
|
||||
} catch (Throwable _e) {
|
||||
throw Exceptions.sneakyThrow(_e);
|
||||
}
|
||||
}
|
||||
|
||||
public static void silentStandardStreams() {
|
||||
ServerLauncher.redirectStandardStreams(ServerLauncher.silentOut());
|
||||
}
|
||||
|
||||
public static void redirectStandardStreams(final OutputStream out) {
|
||||
ServerLauncher.redirectStandardStreams(ServerLauncher.silentIn(), out);
|
||||
}
|
||||
|
||||
public static void redirectStandardStreams(final InputStream in, final OutputStream out) {
|
||||
System.setIn(in);
|
||||
PrintStream _printStream = new PrintStream(out);
|
||||
System.setOut(_printStream);
|
||||
}
|
||||
|
||||
public static OutputStream silentOut() {
|
||||
return ByteStreams.nullOutputStream();
|
||||
}
|
||||
|
||||
public static InputStream silentIn() {
|
||||
byte[] _newByteArrayOfSize = new byte[0];
|
||||
return new ByteArrayInputStream(_newByteArrayOfSize);
|
||||
}
|
||||
}
|
|
@ -1,150 +0,0 @@
|
|||
/**
|
||||
* Copyright (c) 2019 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.server;
|
||||
|
||||
import com.google.common.base.Objects;
|
||||
import com.google.inject.Guice;
|
||||
import com.google.inject.Injector;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.io.PrintWriter;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.SocketAddress;
|
||||
import java.nio.channels.AsynchronousServerSocketChannel;
|
||||
import java.nio.channels.AsynchronousSocketChannel;
|
||||
import java.nio.channels.Channels;
|
||||
import org.apache.log4j.Logger;
|
||||
import org.eclipse.lsp4j.jsonrpc.Launcher;
|
||||
import org.eclipse.lsp4j.services.LanguageClient;
|
||||
import org.eclipse.xtext.ide.server.LanguageServerImpl;
|
||||
import org.eclipse.xtext.ide.server.ServerModule;
|
||||
import org.eclipse.xtext.util.internal.Log;
|
||||
import org.eclipse.xtext.xbase.lib.ArrayExtensions;
|
||||
import org.eclipse.xtext.xbase.lib.Exceptions;
|
||||
|
||||
/**
|
||||
* Allows to launch a language server vie a server socket.
|
||||
*
|
||||
* Useful for debugging live language servers.
|
||||
*
|
||||
* @author Jan Köhnlein - Initial contribution and API
|
||||
* @since 2.18
|
||||
*/
|
||||
@Log
|
||||
@SuppressWarnings("all")
|
||||
public class SocketServerLauncher {
|
||||
public static final String HOST = "-host";
|
||||
|
||||
public static final String PORT = "-port";
|
||||
|
||||
public static final String TRACE = "-trace";
|
||||
|
||||
public static final String NO_VALIDATE = "-noValidate";
|
||||
|
||||
public static final int DEFAULT_PORT = 5008;
|
||||
|
||||
public static final String DEFAULT_HOST = "0.0.0.0";
|
||||
|
||||
public static void main(final String[] args) {
|
||||
new SocketServerLauncher().launch(args);
|
||||
}
|
||||
|
||||
public void launch(final String[] args) {
|
||||
try {
|
||||
final Injector injector = Guice.createInjector(this.getServerModule());
|
||||
final AsynchronousServerSocketChannel serverSocket = AsynchronousServerSocketChannel.open().bind(this.getSocketAddress(args));
|
||||
InetSocketAddress _socketAddress = this.getSocketAddress(args);
|
||||
String _plus = ("Started server socket at " + _socketAddress);
|
||||
SocketServerLauncher.LOG.info(_plus);
|
||||
while (true) {
|
||||
{
|
||||
final AsynchronousSocketChannel socketChannel = serverSocket.accept().get();
|
||||
final InputStream in = Channels.newInputStream(socketChannel);
|
||||
final OutputStream out = Channels.newOutputStream(socketChannel);
|
||||
final PrintWriter trace = this.getTrace(args);
|
||||
final boolean validate = this.shouldValidate(args);
|
||||
final LanguageServerImpl languageServer = injector.<LanguageServerImpl>getInstance(LanguageServerImpl.class);
|
||||
SocketAddress _remoteAddress = socketChannel.getRemoteAddress();
|
||||
String _plus_1 = ("Starting Xtext Language Server for client " + _remoteAddress);
|
||||
SocketServerLauncher.LOG.info(_plus_1);
|
||||
final Launcher<LanguageClient> launcher = Launcher.<LanguageClient>createLauncher(languageServer, LanguageClient.class, in, out, validate, trace);
|
||||
languageServer.connect(launcher.getRemoteProxy());
|
||||
launcher.startListening();
|
||||
SocketServerLauncher.LOG.info("Xtext Language Server has been started.");
|
||||
}
|
||||
}
|
||||
} catch (final Throwable _t) {
|
||||
if (_t instanceof Throwable) {
|
||||
final Throwable throwable = (Throwable)_t;
|
||||
throwable.printStackTrace();
|
||||
} else {
|
||||
throw Exceptions.sneakyThrow(_t);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected com.google.inject.Module getServerModule() {
|
||||
return new ServerModule();
|
||||
}
|
||||
|
||||
protected PrintWriter getTrace(final String... args) {
|
||||
PrintWriter _xifexpression = null;
|
||||
boolean _contains = ArrayExtensions.contains(args, SocketServerLauncher.TRACE);
|
||||
if (_contains) {
|
||||
_xifexpression = new PrintWriter(System.out);
|
||||
}
|
||||
return _xifexpression;
|
||||
}
|
||||
|
||||
protected boolean shouldValidate(final String... args) {
|
||||
boolean _contains = ArrayExtensions.contains(args, SocketServerLauncher.NO_VALIDATE);
|
||||
return (!_contains);
|
||||
}
|
||||
|
||||
protected InetSocketAddress getSocketAddress(final String... args) {
|
||||
String _host = this.getHost(args);
|
||||
int _port = this.getPort(args);
|
||||
return new InetSocketAddress(_host, _port);
|
||||
}
|
||||
|
||||
protected String getHost(final String... args) {
|
||||
String _elvis = null;
|
||||
String _value = this.getValue(args, SocketServerLauncher.HOST);
|
||||
if (_value != null) {
|
||||
_elvis = _value;
|
||||
} else {
|
||||
_elvis = SocketServerLauncher.DEFAULT_HOST;
|
||||
}
|
||||
return _elvis;
|
||||
}
|
||||
|
||||
protected int getPort(final String... args) {
|
||||
Integer _elvis = null;
|
||||
Integer _integer = Integer.getInteger(this.getValue(args, SocketServerLauncher.PORT));
|
||||
if (_integer != null) {
|
||||
_elvis = _integer;
|
||||
} else {
|
||||
_elvis = Integer.valueOf(SocketServerLauncher.DEFAULT_PORT);
|
||||
}
|
||||
return (int) _elvis;
|
||||
}
|
||||
|
||||
protected String getValue(final String[] args, final String argName) {
|
||||
for (int i = 0; (i < (args.length - 1)); i++) {
|
||||
String _get = args[i];
|
||||
boolean _equals = Objects.equal(_get, argName);
|
||||
if (_equals) {
|
||||
return args[(i + 1)];
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static final Logger LOG = Logger.getLogger(SocketServerLauncher.class);
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
/**
|
||||
* Copyright (c) 2016, 2017 TypeFox GmbH (http://www.typefox.io) and others.
|
||||
* 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.
|
||||
|
@ -12,7 +12,6 @@ import java.util.Collections;
|
|||
import java.util.Map;
|
||||
|
||||
import org.eclipse.lsp4j.InitializeParams;
|
||||
import org.eclipse.xtext.xbase.lib.CollectionLiterals;
|
||||
import org.eclipse.xtext.xbase.lib.Procedures.Procedure1;
|
||||
|
||||
public class TextDocumentConfiguration {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/**
|
||||
* Copyright (c) 2015 itemis AG (http://www.itemis.eu) and others.
|
||||
* 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.
|
||||
|
@ -12,11 +12,9 @@ import com.google.common.annotations.Beta;
|
|||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Target;
|
||||
import org.eclipse.xtend.lib.macro.Active;
|
||||
import org.eclipse.xtext.util.internal.LogProcessor;
|
||||
|
||||
@Beta
|
||||
@Target(ElementType.TYPE)
|
||||
@Active(LogProcessor.class)
|
||||
@SuppressWarnings("all")
|
||||
public @interface Log {
|
||||
}
|
|
@ -1,38 +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.util.internal
|
||||
|
||||
import com.google.common.annotations.Beta
|
||||
import java.lang.annotation.Target
|
||||
import org.apache.log4j.Logger
|
||||
import org.eclipse.xtend.lib.macro.AbstractClassProcessor
|
||||
import org.eclipse.xtend.lib.macro.Active
|
||||
import org.eclipse.xtend.lib.macro.TransformationContext
|
||||
import org.eclipse.xtend.lib.macro.declaration.MutableClassDeclaration
|
||||
|
||||
@Beta
|
||||
@Target(TYPE)
|
||||
@Active(LogProcessor)
|
||||
annotation Log {
|
||||
}
|
||||
|
||||
class LogProcessor extends AbstractClassProcessor {
|
||||
|
||||
override doTransform(MutableClassDeclaration cls, extension TransformationContext context) {
|
||||
cls.addField("LOG") [
|
||||
static = true
|
||||
final = true
|
||||
type = Logger.newTypeReference
|
||||
initializer = '''
|
||||
«Logger».getLogger(«cls.simpleName».class)
|
||||
'''
|
||||
primarySourceElement = cls
|
||||
]
|
||||
}
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
/**
|
||||
* 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.util.internal;
|
||||
|
||||
import org.apache.log4j.Logger;
|
||||
import org.eclipse.xtend.lib.macro.AbstractClassProcessor;
|
||||
import org.eclipse.xtend.lib.macro.TransformationContext;
|
||||
import org.eclipse.xtend.lib.macro.declaration.MutableClassDeclaration;
|
||||
import org.eclipse.xtend2.lib.StringConcatenationClient;
|
||||
|
||||
public class LogProcessor extends AbstractClassProcessor {
|
||||
@Override
|
||||
public void doTransform(MutableClassDeclaration cls, TransformationContext context) {
|
||||
cls.addField("LOG", field -> {
|
||||
field.setStatic(true);
|
||||
field.setFinal(true);
|
||||
field.setType(context.newTypeReference(Logger.class));
|
||||
field.setInitializer(new StringConcatenationClient() {
|
||||
@Override
|
||||
protected void appendTo(TargetStringConcatenation target) {
|
||||
target.append(Logger.class);
|
||||
target.append(".getLogger(");
|
||||
target.append(cls.getSimpleName());
|
||||
target.append(".class)");
|
||||
target.newLineIfNotEmpty();
|
||||
}
|
||||
});
|
||||
context.setPrimarySourceElement(field, cls);
|
||||
});
|
||||
}
|
||||
}
|
|
@ -1,44 +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.util.internal;
|
||||
|
||||
import org.apache.log4j.Logger;
|
||||
import org.eclipse.xtend.lib.macro.AbstractClassProcessor;
|
||||
import org.eclipse.xtend.lib.macro.TransformationContext;
|
||||
import org.eclipse.xtend.lib.macro.declaration.MutableClassDeclaration;
|
||||
import org.eclipse.xtend.lib.macro.declaration.MutableFieldDeclaration;
|
||||
import org.eclipse.xtend2.lib.StringConcatenationClient;
|
||||
import org.eclipse.xtext.xbase.lib.Extension;
|
||||
import org.eclipse.xtext.xbase.lib.Procedures.Procedure1;
|
||||
|
||||
@SuppressWarnings("all")
|
||||
public class LogProcessor extends AbstractClassProcessor {
|
||||
@Override
|
||||
public void doTransform(final MutableClassDeclaration cls, @Extension final TransformationContext context) {
|
||||
final Procedure1<MutableFieldDeclaration> _function = (MutableFieldDeclaration it) -> {
|
||||
it.setStatic(true);
|
||||
it.setFinal(true);
|
||||
it.setType(context.newTypeReference(Logger.class));
|
||||
StringConcatenationClient _client = new StringConcatenationClient() {
|
||||
@Override
|
||||
protected void appendTo(StringConcatenationClient.TargetStringConcatenation _builder) {
|
||||
_builder.append(Logger.class);
|
||||
_builder.append(".getLogger(");
|
||||
String _simpleName = cls.getSimpleName();
|
||||
_builder.append(_simpleName);
|
||||
_builder.append(".class)");
|
||||
_builder.newLineIfNotEmpty();
|
||||
}
|
||||
};
|
||||
it.setInitializer(_client);
|
||||
context.setPrimarySourceElement(it, cls);
|
||||
};
|
||||
cls.addField("LOG", _function);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,74 @@
|
|||
/**
|
||||
* 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.wizard.cli;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
||||
import org.eclipse.xtext.util.Strings;
|
||||
import org.eclipse.xtext.xbase.lib.Exceptions;
|
||||
import org.eclipse.xtext.xtext.wizard.AbstractFile;
|
||||
import org.eclipse.xtext.xtext.wizard.BinaryFile;
|
||||
import org.eclipse.xtext.xtext.wizard.ProjectDescriptor;
|
||||
import org.eclipse.xtext.xtext.wizard.ProjectsCreator;
|
||||
import org.eclipse.xtext.xtext.wizard.SourceFolderDescriptor;
|
||||
import org.eclipse.xtext.xtext.wizard.TextFile;
|
||||
import org.eclipse.xtext.xtext.wizard.WizardConfiguration;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import com.google.common.io.Files;
|
||||
import com.google.common.io.Resources;
|
||||
|
||||
public class CliProjectsCreator implements ProjectsCreator {
|
||||
private String lineDelimiter;
|
||||
|
||||
@Override
|
||||
public void createProjects(WizardConfiguration config) {
|
||||
for (ProjectDescriptor p : config.getEnabledProjects()) {
|
||||
createProject(p);
|
||||
}
|
||||
}
|
||||
|
||||
public void createProject(ProjectDescriptor project) {
|
||||
Preconditions.checkNotNull(lineDelimiter, "lineDelimiter may not be null");
|
||||
try {
|
||||
File projectRoot = new File(project.getLocation());
|
||||
projectRoot.mkdirs();
|
||||
for (AbstractFile f : project.getFiles()) {
|
||||
String outletPath = project.getConfig().getSourceLayout().getPathFor(f.getOutlet());
|
||||
String projectRelativePath = outletPath + "/" + f.getRelativePath();
|
||||
File file = new File(projectRoot, projectRelativePath);
|
||||
file.getParentFile().mkdirs();
|
||||
if (f instanceof TextFile) {
|
||||
String normalizedContent = ((TextFile) f).getContent().replace(Strings.newLine(),
|
||||
lineDelimiter);
|
||||
Files.asCharSink(file, project.getConfig().getEncoding()).write(normalizedContent);
|
||||
} else if (f instanceof BinaryFile) {
|
||||
Files.write(Resources.toByteArray(((BinaryFile) f).getContent()), file);
|
||||
}
|
||||
if (f.isExecutable()) {
|
||||
file.setExecutable(true);
|
||||
}
|
||||
}
|
||||
for (SourceFolderDescriptor folder : project.getSourceFolders()) {
|
||||
new File(projectRoot, folder.getPath()).mkdirs();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw Exceptions.sneakyThrow(e);
|
||||
}
|
||||
}
|
||||
|
||||
public String getLineDelimiter() {
|
||||
return lineDelimiter;
|
||||
}
|
||||
|
||||
public void setLineDelimiter(String lineDelimiter) {
|
||||
this.lineDelimiter = lineDelimiter;
|
||||
}
|
||||
}
|
|
@ -1,57 +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.wizard.cli
|
||||
|
||||
import com.google.common.io.Files
|
||||
import java.io.File
|
||||
import org.eclipse.xtext.xtext.wizard.ProjectDescriptor
|
||||
import org.eclipse.xtext.xtext.wizard.ProjectsCreator
|
||||
import org.eclipse.xtext.xtext.wizard.WizardConfiguration
|
||||
import org.eclipse.xtend.lib.annotations.Accessors
|
||||
import org.eclipse.xtext.util.Strings
|
||||
import org.eclipse.xtext.xtext.wizard.TextFile
|
||||
import org.eclipse.xtext.xtext.wizard.BinaryFile
|
||||
import com.google.common.io.Resources
|
||||
|
||||
class CliProjectsCreator implements ProjectsCreator {
|
||||
|
||||
@Accessors String lineDelimiter
|
||||
|
||||
override createProjects(WizardConfiguration config) {
|
||||
config.enabledProjects.forEach [
|
||||
createProject
|
||||
]
|
||||
}
|
||||
|
||||
def createProject(ProjectDescriptor project) {
|
||||
val projectRoot = new File(project.location)
|
||||
projectRoot.mkdirs
|
||||
project.files.forEach [
|
||||
val projectRelativePath = project.config.sourceLayout.getPathFor(outlet) + "/" + relativePath
|
||||
val file = new File(projectRoot, projectRelativePath)
|
||||
file.parentFile.mkdirs
|
||||
switch(it) {
|
||||
TextFile : {
|
||||
val normalizedContent = content.replace(Strings.newLine, lineDelimiter)
|
||||
Files.asCharSink(file, project.config.encoding).write(normalizedContent)
|
||||
}
|
||||
BinaryFile: {
|
||||
Files.write(Resources.toByteArray(content), file)
|
||||
}
|
||||
}
|
||||
if(executable) {
|
||||
file.executable = true
|
||||
}
|
||||
]
|
||||
project.sourceFolders.forEach [
|
||||
new File(projectRoot, it.path).mkdirs
|
||||
]
|
||||
}
|
||||
|
||||
}
|
|
@ -1,88 +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.wizard.cli;
|
||||
|
||||
import com.google.common.io.Files;
|
||||
import com.google.common.io.Resources;
|
||||
import java.io.File;
|
||||
import java.util.function.Consumer;
|
||||
import org.eclipse.xtend.lib.annotations.Accessors;
|
||||
import org.eclipse.xtext.util.Strings;
|
||||
import org.eclipse.xtext.xbase.lib.Exceptions;
|
||||
import org.eclipse.xtext.xbase.lib.Pure;
|
||||
import org.eclipse.xtext.xtext.wizard.AbstractFile;
|
||||
import org.eclipse.xtext.xtext.wizard.BinaryFile;
|
||||
import org.eclipse.xtext.xtext.wizard.ProjectDescriptor;
|
||||
import org.eclipse.xtext.xtext.wizard.ProjectsCreator;
|
||||
import org.eclipse.xtext.xtext.wizard.SourceFolderDescriptor;
|
||||
import org.eclipse.xtext.xtext.wizard.TextFile;
|
||||
import org.eclipse.xtext.xtext.wizard.WizardConfiguration;
|
||||
|
||||
@SuppressWarnings("all")
|
||||
public class CliProjectsCreator implements ProjectsCreator {
|
||||
@Accessors
|
||||
private String lineDelimiter;
|
||||
|
||||
@Override
|
||||
public void createProjects(final WizardConfiguration config) {
|
||||
final Consumer<ProjectDescriptor> _function = (ProjectDescriptor it) -> {
|
||||
this.createProject(it);
|
||||
};
|
||||
config.getEnabledProjects().forEach(_function);
|
||||
}
|
||||
|
||||
public void createProject(final ProjectDescriptor project) {
|
||||
String _location = project.getLocation();
|
||||
final File projectRoot = new File(_location);
|
||||
projectRoot.mkdirs();
|
||||
final Consumer<AbstractFile> _function = (AbstractFile it) -> {
|
||||
try {
|
||||
String _pathFor = project.getConfig().getSourceLayout().getPathFor(it.getOutlet());
|
||||
String _plus = (_pathFor + "/");
|
||||
String _relativePath = it.getRelativePath();
|
||||
final String projectRelativePath = (_plus + _relativePath);
|
||||
final File file = new File(projectRoot, projectRelativePath);
|
||||
file.getParentFile().mkdirs();
|
||||
boolean _matched = false;
|
||||
if (it instanceof TextFile) {
|
||||
_matched=true;
|
||||
final String normalizedContent = ((TextFile)it).getContent().replace(Strings.newLine(), this.lineDelimiter);
|
||||
Files.asCharSink(file, project.getConfig().getEncoding()).write(normalizedContent);
|
||||
}
|
||||
if (!_matched) {
|
||||
if (it instanceof BinaryFile) {
|
||||
_matched=true;
|
||||
Files.write(Resources.toByteArray(((BinaryFile)it).getContent()), file);
|
||||
}
|
||||
}
|
||||
boolean _isExecutable = it.isExecutable();
|
||||
if (_isExecutable) {
|
||||
file.setExecutable(true);
|
||||
}
|
||||
} catch (Throwable _e) {
|
||||
throw Exceptions.sneakyThrow(_e);
|
||||
}
|
||||
};
|
||||
project.getFiles().forEach(_function);
|
||||
final Consumer<SourceFolderDescriptor> _function_1 = (SourceFolderDescriptor it) -> {
|
||||
String _path = it.getPath();
|
||||
new File(projectRoot, _path).mkdirs();
|
||||
};
|
||||
project.getSourceFolders().forEach(_function_1);
|
||||
}
|
||||
|
||||
@Pure
|
||||
public String getLineDelimiter() {
|
||||
return this.lineDelimiter;
|
||||
}
|
||||
|
||||
public void setLineDelimiter(final String lineDelimiter) {
|
||||
this.lineDelimiter = lineDelimiter;
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue