blob: f3f9afd823a5c305f02b20505c1669921520ae66 [file] [log] [blame]
/**
*
* Copyright (c) 2011, 2016 - Loetz GmbH&Co.KG (69115 Heidelberg, Germany)
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Christophe Loetz (Loetz GmbH&Co.KG) - initial implementation
*
*
* This copyright notice shows up in the generated Java code
*
*/
package org.eclipse.osbp.xtext.messagedsl.ui.contentassist
import com.google.inject.Inject
import java.util.TreeMap
import org.eclipse.emf.ecore.EObject
import org.eclipse.jface.viewers.StyledString
import org.eclipse.osbp.xtext.basic.ui.contentassist.BasicDSLProposalProviderHelper
import org.eclipse.osbp.xtext.messagedsl.MessageItem
import org.eclipse.osbp.xtext.messagedsl.ui.MessageDslUiDocumentationTranslator
import org.eclipse.swt.graphics.Image
import org.eclipse.xtext.Assignment
import org.eclipse.xtext.Keyword
import org.eclipse.xtext.RuleCall
import org.eclipse.xtext.common.ui.contentassist.TerminalsProposalProvider
import org.eclipse.xtext.ui.editor.contentassist.ConfigurableCompletionProposal
import org.eclipse.xtext.ui.editor.contentassist.ContentAssistContext
import org.eclipse.xtext.ui.editor.contentassist.ICompletionProposalAcceptor
import org.eclipse.xtext.xbase.jvmmodel.JvmTypesBuilder
/**
* see https://eclipse.org/Xtext/documentation/304_ide_concepts.html#content-assist on how to customize content assistant
*/
class MessageDslProposalProvider extends AbstractMessageDslProposalProvider {
@Inject TerminalsProposalProvider provider
@Inject BasicDSLProposalProviderHelper providerHelper
/**
* @see BasicDSLProposalProviderHelper#getKeywordDisplayString(Keyword, BasicDSLUiTranslator)
* @param keyword the keyword to get the displayed string for
* @return the displayed string
*/
override protected StyledString getKeywordDisplayString(Keyword keyword) {
return BasicDSLProposalProviderHelper.getKeywordDisplayString(keyword, MessageDslUiDocumentationTranslator.instance())
}
/**
* This override will enable 1 length non letter characters as keyword.
*/
override protected boolean isKeywordWorthyToPropose(Keyword keyword) {
true
}
/**
* convenience API to build and initialize JVM types and their members.
*/
@Inject extension JvmTypesBuilder
override public void complete_QualifiedName(EObject model, RuleCall ruleCall, ContentAssistContext context,
ICompletionProposalAcceptor acceptor) {
providerHelper.complete_PackageName(model, ruleCall, context, acceptor, this)
}
/**
* see also {@link org.eclipse.osbp.xtext.messagedsl.common.Message.prepareMessage()}
*/
override void completeMessageText_Text(EObject model, Assignment assignment, ContentAssistContext context, ICompletionProposalAcceptor acceptor) {
// call implementation of superclass
super.completeMessageText_Text(model, assignment, context, acceptor);
// get all parameters given so far
// generate all available variables depending on type of the parameter
// check if the variable already inside the text
val available = new TreeMap<String,String>
val used = new TreeMap<String,String>
val image = null as Image;
val document = context.viewer.document.get.replace("\\\"", "''")
val formatoffset = context.replaceRegion.offset
val nextquote = document.indexOf('"', formatoffset+1)
val replaceRegion = document.substring(formatoffset, nextquote+1)
(model as MessageItem).parameters.forEach [ parameter |
switch (parameter.oftype) {
case BOOLEAN: {
val proposal = '''%%«parameter.name»%%'''
val displayString = '''«proposal» (boolean) «parameter.documentation»'''
if (replaceRegion.contains(proposal)) {
used.put(proposal, '''used: «displayString»''')
}
else {
available.put(proposal, displayString)
}
}
case INTEGER: {
val proposal = '''%%«parameter.name»%%'''
val displayString = '''«proposal» (int) «parameter.documentation»'''
if (replaceRegion.contains(proposal)) {
used.put(proposal, '''used: «displayString»''')
}
else {
available.put(proposal, displayString)
}
}
case DOUBLE: {
val proposal = '''%%«parameter.name»%%'''
val displayString = '''«proposal» (double) «parameter.documentation»'''
if (replaceRegion.contains(proposal)) {
used.put(proposal, '''used: «displayString»''')
}
else {
available.put(proposal, displayString)
}
}
case STRING: {
val proposal = '''%%«parameter.name»%%'''
val displayString = '''«proposal» (String) «parameter.documentation»'''
if (replaceRegion.contains(proposal)) {
used.put(proposal, '''used: «displayString»''')
}
else {
available.put(proposal, displayString)
}
}
case CLASS: {
{
val proposal = '''%%«parameter.name».canonicalName%%'''
val displayString = '''«proposal» (canonical name for Class) «parameter.documentation»'''
if (replaceRegion.contains(proposal)) {
used.put(proposal, '''used: «displayString»''')
}
else {
available.put(proposal, displayString)
}
}
{
val proposal = '''%%«parameter.name».simpleName%%'''
val displayString = '''«proposal» (simple name for Class) «parameter.documentation»'''
if (replaceRegion.contains(proposal)) {
used.put(proposal, '''used: «displayString»''')
}
else {
available.put(proposal, displayString)
}
}
}
case OBJECT: {
{
val proposal = '''%%«parameter.name».canonicalName%%'''
val displayString = '''«proposal» (canonical name for Object) «parameter.documentation»'''
if (replaceRegion.contains(proposal)) {
used.put(proposal, '''used: «displayString»''')
}
else {
available.put(proposal, displayString)
}
}
{
val proposal = '''%%«parameter.name».simpleName%%'''
val displayString = '''«proposal» (simple name for Object) «parameter.documentation»'''
if (replaceRegion.contains(proposal)) {
used.put(proposal, '''used: «displayString»''')
}
else {
available.put(proposal, displayString)
}
}
}
case EXCEPTION: {
{
val proposal = '''%%«parameter.name».canonicalName%%'''
val displayString = '''«proposal» (canonical name for Exception) «parameter.documentation»'''
if (replaceRegion.contains(proposal)) {
used.put(proposal, '''used: «displayString»''')
}
else {
available.put(proposal, displayString)
}
}
{
val proposal = '''%%«parameter.name».simpleName%%'''
val displayString = '''«proposal» (simple name for Exception) «parameter.documentation»'''
if (replaceRegion.contains(proposal)) {
used.put(proposal, '''used: «displayString»''')
}
else {
available.put(proposal, displayString)
}
}
{
val proposal = '''%%«parameter.name».localizedMessage%%'''
val displayString = '''«proposal» (localized message for Exception) «parameter.documentation»'''
if (replaceRegion.contains(proposal)) {
used.put(proposal, '''used: «displayString»''')
}
else {
available.put(proposal, displayString)
}
}
{
val proposal = '''%%«parameter.name».localizedDetailMessage%%'''
val displayString = '''«proposal» (localized detail message for Exception) «parameter.documentation»'''
if (replaceRegion.contains(proposal)) {
used.put(proposal, '''used: «displayString»''')
}
else {
available.put(proposal, displayString)
}
}
{
val proposal = '''%%«parameter.name».localizedSimpleDetailMessage%%'''
val displayString = '''«proposal» (localized simple detail message for Exception) «parameter.documentation»'''
if (replaceRegion.contains(proposal)) {
used.put(proposal, '''used: «displayString»''')
}
else {
available.put(proposal, displayString)
}
}
{
val proposal = '''%%«parameter.name».stackTrace%%'''
val displayString = '''«proposal» (stack trace for Exception) «parameter.documentation»'''
if (replaceRegion.contains(proposal)) {
used.put(proposal, '''used: «displayString»''')
}
else {
available.put(proposal, displayString)
}
}
}
}
]
// Create and register the completion proposal:
// The proposal may be null as the createCompletionProposal(..)
// methods check for valid prefixes and terminal token conflicts.
// The acceptor handles null-values gracefully.
/* */
available.forEach[ proposal, displayString |
acceptor.accept(doCreateInStringProposal(proposal, new StyledString(displayString), image,
getPriorityHelper().getDefaultPriority(), context));
]
used.forEach[ proposal, displayString |
acceptor.accept(doCreateInStringProposal(proposal, new StyledString(displayString), image,
getPriorityHelper().getDefaultPriority(), context));
]
}
def private ConfigurableCompletionProposal doCreateInStringProposal(String proposal, StyledString displayString, Image image,
int priority, ContentAssistContext context) {
val selectedRange = context.viewer.getSelectedRange()
val replacementOffset = selectedRange.x; // context.getReplaceRegion().getOffset();
val replacementLength = selectedRange.y; // context.getReplaceRegion().getLength();
val result = //doCreateProposal(proposal, displayString, image, replacementOffset, replacementLength);
new InsideStringConfigurableCompletionProposal(proposal, replacementOffset, replacementLength, proposal.length(),
image, displayString, null, null);
result.setPriority(priority);
result.setMatcher(context.getMatcher());
result.setReplaceContextLength(context.getReplaceContextLength());
return result;
}
// ------------------------ delegates to TerminalsProposalProvider -----------------
override public void complete_ID(EObject model, RuleCall ruleCall, ContentAssistContext context,
ICompletionProposalAcceptor acceptor) {
provider.complete_ID(model, ruleCall, context, acceptor)
}
}