Skip to content

Commit

Permalink
KOGITO-4233: [DMN Designer] IntelliSense service (#3590)
Browse files Browse the repository at this point in the history
* Update 'kie-wb-common-dmn-client' with new code completion logic

* Update 'kie-wb-common-dmn-webapp-kogito-testing' with FEEL editor component (it's used for development purposes only)

* Update 'kie-wb-common-dmn-webapp-kogito-runtime' and 'kie-wb-common-dmn-webapp-standalone' pom.xml files

* - Remove 'DefaultedVisitor' class
 - Update the date in copyright headers
 - Additional coverage

* Sanity check of suggestions ordered by type compatibility

* Rollback Candidate.java

Co-authored-by: Jozef Marko <jomarko@redhat.com>
  • Loading branch information
karreiro and Jozef Marko committed Mar 26, 2021
1 parent b1cc5c7 commit 06e5732
Show file tree
Hide file tree
Showing 32 changed files with 2,849 additions and 828 deletions.
25 changes: 25 additions & 0 deletions kie-wb-common-dmn/kie-wb-common-dmn-client/pom.xml
Expand Up @@ -269,6 +269,31 @@
<artifactId>ahome-tooling-nativetools</artifactId>
</dependency>

<dependency>
<groupId>org.kie</groupId>
<artifactId>kie-dmn-feel-gwt-functions</artifactId>
</dependency>
<dependency>
<groupId>org.kie</groupId>
<artifactId>kie-dmn-feel-gwt</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.kie</groupId>
<artifactId>kie-dmn-feel-gwt</artifactId>
<classifier>sources</classifier>
</dependency>
<dependency>
<groupId>org.rikkola.gwt</groupId>
<artifactId>antlr4-c3-gwt</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.antlr</groupId>
<artifactId>antlr4gwt-runtime</artifactId>
<scope>provided</scope>
</dependency>

<!-- Test -->
<dependency>
<groupId>org.mockito</groupId>
Expand Down
Expand Up @@ -54,12 +54,12 @@ public class MonacoFEELInitializer {
"true",
"false"
);
private final MonacoFEELVariableSuggestions variableSuggestions;
private final MonacoSuggestionsPropertyFactory suggestionsPropertyFactory;
private MonacoFEELInitializationStatus initializationStatus = NOT_INITIALIZED;

@Inject
public MonacoFEELInitializer(final MonacoFEELVariableSuggestions variableSuggestions) {
this.variableSuggestions = variableSuggestions;
public MonacoFEELInitializer(final MonacoSuggestionsPropertyFactory suggestionsPropertyFactory) {
this.suggestionsPropertyFactory = suggestionsPropertyFactory;
}

public void initializeFEELEditor() {
Expand All @@ -75,7 +75,7 @@ public void initializeFEELEditor() {
MonacoLanguages.get().setMonarchTokensProvider(FEEL_LANGUAGE_ID,
properties.getLanguageDefinition());
MonacoLanguages.get().registerCompletionItemProvider(FEEL_LANGUAGE_ID,
properties.getCompletionItemProvider(variableSuggestions));
properties.getCompletionItemProvider(suggestionsPropertyFactory));
MonacoEditor.get().defineTheme(FEEL_THEME_ID,
properties.getThemeData());
setFEELAsInitialized();
Expand Down
@@ -0,0 +1,112 @@
/*
* Copyright 2021 Red Hat, Inc. and/or its affiliates.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.kie.workbench.common.dmn.client.widgets.codecompletion;

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

import javax.enterprise.context.ApplicationScoped;
import javax.inject.Inject;

import elemental2.dom.DomGlobal;
import org.kie.dmn.feel.lang.Type;
import org.kie.dmn.feel.lang.types.BuiltInType;
import org.kie.workbench.common.dmn.api.definition.HasVariable;
import org.kie.workbench.common.dmn.api.definition.model.NamedElement;
import org.kie.workbench.common.dmn.api.property.dmn.Name;
import org.kie.workbench.common.dmn.client.graph.DMNGraphUtils;
import org.kie.workbench.common.dmn.client.widgets.codecompletion.feel.Candidate;
import org.kie.workbench.common.dmn.client.widgets.codecompletion.feel.FEELLanguageService;
import org.kie.workbench.common.dmn.client.widgets.codecompletion.feel.FEELLanguageService.Position;
import org.kie.workbench.common.dmn.client.widgets.codecompletion.feel.Variable;
import org.kie.workbench.common.stunner.core.graph.Node;
import org.kie.workbench.common.stunner.core.graph.content.definition.Definition;

import static org.kie.dmn.feel.lang.types.BuiltInType.determineTypeFromName;

@ApplicationScoped
public class MonacoFEELSuggestions {

private final DMNGraphUtils dmnGraphUtils;

private final FEELLanguageService feelLanguageService;

@Inject
public MonacoFEELSuggestions(final DMNGraphUtils dmnGraphUtils,
final FEELLanguageService feelLanguageService) {
this.dmnGraphUtils = dmnGraphUtils;
this.feelLanguageService = feelLanguageService;
}

public List<Candidate> getCandidates(final String expression,
final Position position) {
try {
return feelLanguageService.getCandidates(expression, getNodesVariables(), position);
} catch (final Exception e) {
warn("[FEELLanguageService] Error: Candidates could not be processed.");
return new ArrayList<>();
}
}

private List<Variable> getNodesVariables() {
return getDiagramDefinitions()
.stream()
.map(this::asVariable)
.filter(Optional::isPresent)
.map(Optional::get)
.collect(Collectors.toList());
}

private Optional<Variable> asVariable(final Object definition) {
if (definition instanceof NamedElement) {
return Optional.of(new Variable(getName(definition), getType(definition)));
}
return Optional.empty();
}

private String getName(final Object definition) {
final NamedElement namedElement = (NamedElement) definition;
final Name name = namedElement.getName();
return name.getValue();
}

private Type getType(final Object definition) {
try {
final HasVariable<?> hasVariable = (HasVariable<?>) definition;
final String localPart = hasVariable.getVariable().getTypeRef().getLocalPart();
return determineTypeFromName(localPart);
} catch (final Exception e) {
return BuiltInType.UNKNOWN;
}
}

private List<Object> getDiagramDefinitions() {
return dmnGraphUtils
.getNodeStream()
.map(Node::getContent)
.filter(c -> c instanceof Definition)
.map(c -> (Definition<?>) c)
.map(Definition::getDefinition)
.collect(Collectors.toList());
}

void warn(final String message) {
DomGlobal.console.warn(message);
}
}

This file was deleted.

0 comments on commit 06e5732

Please sign in to comment.