diff --git a/org.eclipse.xtext.ide/src/org/eclipse/xtext/ide/editor/contentassist/AbstractIdeTemplateProposalProvider.java b/org.eclipse.xtext.ide/src/org/eclipse/xtext/ide/editor/contentassist/AbstractIdeTemplateProposalProvider.java new file mode 100644 index 000000000..c12d94771 --- /dev/null +++ b/org.eclipse.xtext.ide/src/org/eclipse/xtext/ide/editor/contentassist/AbstractIdeTemplateProposalProvider.java @@ -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. + *
+ * 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);
+ * 
+ * + * @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; + } +} diff --git a/org.eclipse.xtext.ide/src/org/eclipse/xtext/ide/editor/contentassist/AbstractIdeTemplateProposalProvider.xtend b/org.eclipse.xtext.ide/src/org/eclipse/xtext/ide/editor/contentassist/AbstractIdeTemplateProposalProvider.xtend deleted file mode 100644 index 4606501e2..000000000 --- a/org.eclipse.xtext.ide/src/org/eclipse/xtext/ide/editor/contentassist/AbstractIdeTemplateProposalProvider.xtend +++ /dev/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. - *
- * val StringConcatenationClient template = '''
- *     state «variable('name')»
- *         «cursor»
- *     end
- * '''
- * acceptProposal('state', 'Create a new state', template, context, acceptor)
- * 
- * - * @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() - } - - } - -} \ No newline at end of file diff --git a/org.eclipse.xtext.ide/src/org/eclipse/xtext/ide/server/ServerLauncher.java b/org.eclipse.xtext.ide/src/org/eclipse/xtext/ide/server/ServerLauncher.java new file mode 100644 index 000000000..b1c396221 --- /dev/null +++ b/org.eclipse.xtext.ide/src/org/eclipse/xtext/ide/server/ServerLauncher.java @@ -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).getInstance(ServerLauncher.class); + launcher.start(launchArgs); + } + + @Inject + private LanguageServerImpl languageServer; + + public void start(LaunchArgs args) { + try { + InputOutput.println("Xtext Language Server is starting."); + Launcher launcher = Launcher.createLauncher(languageServer, + LanguageClient.class, args.getIn(), args.getOut(), args.isValidate(), args.getTrace()); + languageServer.connect(launcher.getRemoteProxy()); + Future 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]); + } +} diff --git a/org.eclipse.xtext.ide/src/org/eclipse/xtext/ide/server/ServerLauncher.xtend b/org.eclipse.xtext.ide/src/org/eclipse/xtext/ide/server/ServerLauncher.xtend deleted file mode 100644 index 19d3a9887..000000000 --- a/org.eclipse.xtext.ide/src/org/eclipse/xtext/ide/server/ServerLauncher.xtend +++ /dev/null @@ -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)) - } - -} diff --git a/org.eclipse.xtext.ide/src/org/eclipse/xtext/ide/server/SocketServerLauncher.java b/org.eclipse.xtext.ide/src/org/eclipse/xtext/ide/server/SocketServerLauncher.java new file mode 100644 index 000000000..daebf67c6 --- /dev/null +++ b/org.eclipse.xtext.ide/src/org/eclipse/xtext/ide/server/SocketServerLauncher.java @@ -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 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; + } +} diff --git a/org.eclipse.xtext.ide/src/org/eclipse/xtext/ide/server/SocketServerLauncher.xtend b/org.eclipse.xtext.ide/src/org/eclipse/xtext/ide/server/SocketServerLauncher.xtend deleted file mode 100644 index b4309042d..000000000 --- a/org.eclipse.xtext.ide/src/org/eclipse/xtext/ide/server/SocketServerLauncher.xtend +++ /dev/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 - } -} diff --git a/org.eclipse.xtext.ide/xtend-gen/org/eclipse/xtext/ide/editor/contentassist/AbstractIdeTemplateProposalProvider.java b/org.eclipse.xtext.ide/xtend-gen/org/eclipse/xtext/ide/editor/contentassist/AbstractIdeTemplateProposalProvider.java deleted file mode 100644 index 7c1321fad..000000000 --- a/org.eclipse.xtext.ide/xtend-gen/org/eclipse/xtext/ide/editor/contentassist/AbstractIdeTemplateProposalProvider.java +++ /dev/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. - *
- * val StringConcatenationClient template = '''
- *     state «variable('name')»
- *         «cursor»
- *     end
- * '''
- * acceptProposal('state', 'Create a new state', template, context, acceptor)
- * 
- * - * @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 _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 _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; - } -} diff --git a/org.eclipse.xtext.ide/xtend-gen/org/eclipse/xtext/ide/server/ServerLauncher.java b/org.eclipse.xtext.ide/xtend-gen/org/eclipse/xtext/ide/server/ServerLauncher.java deleted file mode 100644 index dd2f26320..000000000 --- a/org.eclipse.xtext.ide/xtend-gen/org/eclipse/xtext/ide/server/ServerLauncher.java +++ /dev/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).getInstance(ServerLauncher.class); - launcher.start(launchArgs); - } - - @Inject - private LanguageServerImpl languageServer; - - public void start(final LaunchArgs it) { - try { - InputOutput.println("Xtext Language Server is starting."); - final Launcher launcher = Launcher.createLauncher(this.languageServer, LanguageClient.class, it.getIn(), it.getOut(), it.isValidate(), it.getTrace()); - this.languageServer.connect(launcher.getRemoteProxy()); - final Future future = launcher.startListening(); - InputOutput.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 _function = (String arg) -> { - return Boolean.valueOf(ServerLauncher.testArg(arg, values)); - }; - return IterableExtensions.exists(((Iterable)Conversions.doWrapArray(args)), _function); - } - - public static boolean testArg(final String arg, final String... values) { - final Function1 _function = (String value) -> { - return Boolean.valueOf(Objects.equal(value, arg)); - }; - return IterableExtensions.exists(((Iterable)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); - } -} diff --git a/org.eclipse.xtext.ide/xtend-gen/org/eclipse/xtext/ide/server/SocketServerLauncher.java b/org.eclipse.xtext.ide/xtend-gen/org/eclipse/xtext/ide/server/SocketServerLauncher.java deleted file mode 100644 index 839355052..000000000 --- a/org.eclipse.xtext.ide/xtend-gen/org/eclipse/xtext/ide/server/SocketServerLauncher.java +++ /dev/null @@ -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.getInstance(LanguageServerImpl.class); - SocketAddress _remoteAddress = socketChannel.getRemoteAddress(); - String _plus_1 = ("Starting Xtext Language Server for client " + _remoteAddress); - SocketServerLauncher.LOG.info(_plus_1); - final Launcher launcher = Launcher.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); -} diff --git a/org.eclipse.xtext.testing/src/org/eclipse/xtext/testing/TextDocumentConfiguration.java b/org.eclipse.xtext.testing/src/org/eclipse/xtext/testing/TextDocumentConfiguration.java index 05b37d57b..caef151bf 100644 --- a/org.eclipse.xtext.testing/src/org/eclipse/xtext/testing/TextDocumentConfiguration.java +++ b/org.eclipse.xtext.testing/src/org/eclipse/xtext/testing/TextDocumentConfiguration.java @@ -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 { diff --git a/org.eclipse.xtext.util/xtend-gen/org/eclipse/xtext/util/internal/Log.java b/org.eclipse.xtext.util/src/org/eclipse/xtext/util/internal/Log.java similarity index 78% rename from org.eclipse.xtext.util/xtend-gen/org/eclipse/xtext/util/internal/Log.java rename to org.eclipse.xtext.util/src/org/eclipse/xtext/util/internal/Log.java index d0e532b67..a47a2a7f6 100644 --- a/org.eclipse.xtext.util/xtend-gen/org/eclipse/xtext/util/internal/Log.java +++ b/org.eclipse.xtext.util/src/org/eclipse/xtext/util/internal/Log.java @@ -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 { } diff --git a/org.eclipse.xtext.util/src/org/eclipse/xtext/util/internal/Log.xtend b/org.eclipse.xtext.util/src/org/eclipse/xtext/util/internal/Log.xtend deleted file mode 100644 index e90ef0a85..000000000 --- a/org.eclipse.xtext.util/src/org/eclipse/xtext/util/internal/Log.xtend +++ /dev/null @@ -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 - ] - } -} \ No newline at end of file diff --git a/org.eclipse.xtext.util/src/org/eclipse/xtext/util/internal/LogProcessor.java b/org.eclipse.xtext.util/src/org/eclipse/xtext/util/internal/LogProcessor.java new file mode 100644 index 000000000..3ee3f9481 --- /dev/null +++ b/org.eclipse.xtext.util/src/org/eclipse/xtext/util/internal/LogProcessor.java @@ -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); + }); + } +} diff --git a/org.eclipse.xtext.util/xtend-gen/org/eclipse/xtext/util/internal/LogProcessor.java b/org.eclipse.xtext.util/xtend-gen/org/eclipse/xtext/util/internal/LogProcessor.java deleted file mode 100644 index 9e43a3b63..000000000 --- a/org.eclipse.xtext.util/xtend-gen/org/eclipse/xtext/util/internal/LogProcessor.java +++ /dev/null @@ -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 _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); - } -} diff --git a/org.eclipse.xtext.xtext.wizard/src/org/eclipse/xtext/xtext/wizard/cli/CliProjectsCreator.java b/org.eclipse.xtext.xtext.wizard/src/org/eclipse/xtext/xtext/wizard/cli/CliProjectsCreator.java new file mode 100644 index 000000000..dc11cc8f0 --- /dev/null +++ b/org.eclipse.xtext.xtext.wizard/src/org/eclipse/xtext/xtext/wizard/cli/CliProjectsCreator.java @@ -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; + } +} diff --git a/org.eclipse.xtext.xtext.wizard/src/org/eclipse/xtext/xtext/wizard/cli/CliProjectsCreator.xtend b/org.eclipse.xtext.xtext.wizard/src/org/eclipse/xtext/xtext/wizard/cli/CliProjectsCreator.xtend deleted file mode 100644 index f1690b6ca..000000000 --- a/org.eclipse.xtext.xtext.wizard/src/org/eclipse/xtext/xtext/wizard/cli/CliProjectsCreator.xtend +++ /dev/null @@ -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 - ] - } - -} \ No newline at end of file diff --git a/org.eclipse.xtext.xtext.wizard/xtend-gen/org/eclipse/xtext/xtext/wizard/cli/CliProjectsCreator.java b/org.eclipse.xtext.xtext.wizard/xtend-gen/org/eclipse/xtext/xtext/wizard/cli/CliProjectsCreator.java deleted file mode 100644 index 92d6e0d61..000000000 --- a/org.eclipse.xtext.xtext.wizard/xtend-gen/org/eclipse/xtext/xtext/wizard/cli/CliProjectsCreator.java +++ /dev/null @@ -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 _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 _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 _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; - } -}