Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[incubator-kie-issues-1752] TCK failure-Lambda function returns null #6261

Open
wants to merge 25 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
404c291
null returned from lambda -issue fixed and added tests
bncriju Feb 20, 2025
f5731cd
Restored singleton patterns for functions used for test
bncriju Feb 20, 2025
367f0e1
Refactored test class and added more tests
bncriju Feb 24, 2025
8bc77b2
Added apache header on new class
bncriju Feb 24, 2025
56620c8
Merge remote-tracking branch 'origin/main' into kie-issues#1752
bncriju Feb 24, 2025
5d4b68f
making doc correct
bncriju Feb 24, 2025
c0123fb
checking invoke method and incorporating review comments
bncriju Feb 26, 2025
5cb934c
Merge remote-tracking branch 'origin/main' into kie-issues#1752
bncriju Feb 26, 2025
61699e3
[incubator-kie-issues#1752] WIP
Feb 26, 2025
17a8abb
isCompatible method test and candidate method modification
bncriju Feb 27, 2025
6f56cfc
Util class added for BuiltInType. Used util method
bncriju Mar 3, 2025
b2b0b03
Merge remote-tracking branch 'origin/main' into kie-issues#1752
bncriju Mar 3, 2025
fe19990
resolved merge conflicts
bncriju Mar 3, 2025
93e22ab
reverting pom changes
bncriju Mar 3, 2025
bc6e374
[incubator-kie-issues#1752] Improve parameters check on BaseFEELFunction
Mar 3, 2025
0560f1f
[incubator-kie-issues#1752] Fix usage of BuiltInTypeUtils inside drl …
Mar 4, 2025
7013c13
adding tests
bncriju Mar 5, 2025
55d173b
Merge remote-tracking branch 'origin/main' into kie-issues#1752
bncriju Mar 5, 2025
62ce7a1
[incubator-kie-issues#1752] WIP - Test suggestion
Mar 5, 2025
365eb15
test suggestions incorporated
bncriju Mar 6, 2025
4995fbd
[incubator-kie-issues#1752] Managing arrays conversion. Begin BuiltIn…
Mar 6, 2025
a69fbe7
tests updated
bncriju Mar 6, 2025
0cc7c2c
Merge remote-tracking branch 'origin/main' into kie-issues#1752
bncriju Mar 7, 2025
5c44070
license header corrected and managed unused imports
bncriju Mar 7, 2025
19fc323
license header corrected
bncriju Mar 7, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/**
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
Expand All @@ -7,7 +7,7 @@
* "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
* 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
Expand All @@ -24,13 +24,12 @@
import org.kie.dmn.api.core.DMNType;
import org.kie.dmn.core.impl.DMNModelImpl;
import org.kie.dmn.feel.lang.Type;
import org.kie.dmn.feel.util.BuiltInTypeUtils;
import org.kie.dmn.model.api.DecisionRule;
import org.kie.dmn.model.api.DecisionTable;
import org.kie.dmn.model.api.InputClause;
import org.kie.dmn.model.api.LiteralExpression;

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

public class TableCellParser {
TableCell.TableCellFactory tableCellFactory;

Expand All @@ -55,9 +54,9 @@ public TableCells parseCells(DecisionTable decisionTable, DTQNameToTypeResolver
final String columnName = column.getInputExpression().getText();
final Type columnType = resolver.resolve(column.getInputExpression().getTypeRef());
TableCell cell = tableCellFactory.createInputCell(tableIndex,
input,
columnName,
columnType);
input,
columnName,
columnType);


tableCells.add(cell);
Expand Down Expand Up @@ -87,13 +86,13 @@ private void parseColumnDefinition(String decisionTableName, List<InputClause> c
for (int columnIndex = 0, columnsSize = columns.size(); columnIndex < columnsSize; columnIndex++) {
InputClause column = columns.get(columnIndex);

Type type = determineTypeFromName(column.getInputExpression().getTypeRef() != null ? column.getInputExpression().getTypeRef().getLocalPart() : null);
Type type = BuiltInTypeUtils.determineTypeFromName(column.getInputExpression().getTypeRef() != null ? column.getInputExpression().getTypeRef().getLocalPart() : null);

tableCells.addColumnCell(columnIndex, tableCellFactory.createColumnDefinition(columnIndex,
decisionTableName,
column.getInputExpression().getText(),
column.getInputValues(),
type));
decisionTableName,
column.getInputExpression().getText(),
column.getInputValues(),
type));
}
}

Expand Down
1,309 changes: 658 additions & 651 deletions kie-dmn/kie-dmn-core/src/test/java/org/kie/dmn/core/DMNRuntimeTest.java

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/**
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,24 +29,29 @@
import org.kie.dmn.feel.runtime.Range;
import org.kie.dmn.feel.runtime.impl.RangeImpl;
import org.kie.dmn.feel.runtime.impl.UndefinedValueComparable;
import org.kie.dmn.feel.util.BuiltInTypeUtils;
import org.kie.dmn.feel.util.Msg;

public class RangeNode
extends BaseNode {

public enum IntervalBoundary {
OPEN, CLOSED;

public static IntervalBoundary low(String input) {
switch (input) {
case "[": return CLOSED;
case "[":
return CLOSED;
case "]":
default:
return OPEN;
return OPEN;
}
}

public static IntervalBoundary high(String input) {
switch (input) {
case "]": return CLOSED;
case "]":
return CLOSED;
case "[":
default:
return OPEN;
Expand All @@ -56,11 +61,11 @@ public static IntervalBoundary high(String input) {

private IntervalBoundary lowerBound;
private IntervalBoundary upperBound;
private BaseNode start;
private BaseNode end;
private BaseNode start;
private BaseNode end;

public RangeNode(ParserRuleContext ctx, IntervalBoundary lowerBound, BaseNode start, BaseNode end, IntervalBoundary upperBound) {
super( ctx );
super(ctx);
this.lowerBound = lowerBound;
this.upperBound = upperBound;
this.start = start;
Expand Down Expand Up @@ -109,30 +114,30 @@ public void setEnd(BaseNode end) {

@Override
public Range evaluate(EvaluationContext ctx) {
Object s = start.evaluate( ctx );
Object e = end.evaluate( ctx );
Object s = start.evaluate(ctx);
Object e = end.evaluate(ctx);
if (s == null || e == null) {
return null;
}
Type sType = BuiltInType.determineTypeFromInstance(s);
Type eType = BuiltInType.determineTypeFromInstance(e);

Type sType = BuiltInTypeUtils.determineTypeFromInstance(s);
Type eType = BuiltInTypeUtils.determineTypeFromInstance(e);
boolean withUndefined = s instanceof UndefinedValueComparable || e instanceof UndefinedValueComparable;
if (s != null && e != null &&
!withUndefined &&
sType != eType &&
!s.getClass().isAssignableFrom(e.getClass())) {
ctx.notifyEvt( astEvent(Severity.ERROR, Msg.createMessage(Msg.X_TYPE_INCOMPATIBLE_WITH_Y_TYPE, "Start", "End")));
ctx.notifyEvt(astEvent(Severity.ERROR, Msg.createMessage(Msg.X_TYPE_INCOMPATIBLE_WITH_Y_TYPE, "Start", "End")));
return null;
}

Comparable start = s instanceof UndefinedValueComparable ? (Comparable) s : convertToComparable(ctx, s );
Comparable end = e instanceof UndefinedValueComparable ? (Comparable) e : convertToComparable( ctx, e );
Comparable start = s instanceof UndefinedValueComparable ? (Comparable) s : convertToComparable(ctx, s);
Comparable end = e instanceof UndefinedValueComparable ? (Comparable) e : convertToComparable(ctx, e);
return isDescendingRange(start, end) ? null :
new RangeImpl( lowerBound==IntervalBoundary.OPEN ? Range.RangeBoundary.OPEN : Range.RangeBoundary.CLOSED,
start,
end,
upperBound==IntervalBoundary.OPEN ? Range.RangeBoundary.OPEN : Range.RangeBoundary.CLOSED );
new RangeImpl(lowerBound == IntervalBoundary.OPEN ? Range.RangeBoundary.OPEN : Range.RangeBoundary.CLOSED,
start,
end,
upperBound == IntervalBoundary.OPEN ? Range.RangeBoundary.OPEN : Range.RangeBoundary.CLOSED);
}

static boolean isDescendingRange(Comparable start, Comparable end) {
Expand All @@ -145,11 +150,11 @@ private Comparable convertToComparable(EvaluationContext ctx, Object s) {
start = null;
} else if (s instanceof Comparable) {
start = (Comparable) s;
} else if( s instanceof Period ) {
} else if (s instanceof Period) {
// period has special semantics
start = new ComparablePeriod( (Period) s );
start = new ComparablePeriod((Period) s);
} else {
ctx.notifyEvt( astEvent(Severity.ERROR, Msg.createMessage(Msg.INCOMPATIBLE_TYPE_FOR_RANGE, s.getClass().getSimpleName() )));
ctx.notifyEvt(astEvent(Severity.ERROR, Msg.createMessage(Msg.INCOMPATIBLE_TYPE_FOR_RANGE, s.getClass().getSimpleName())));
start = null;
}
return start;
Expand All @@ -162,7 +167,7 @@ public Type getResultType() {

@Override
public ASTNode[] getChildrenNode() {
return new ASTNode[] { start, end };
return new ASTNode[]{start, end};
}

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/**
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
Expand All @@ -7,7 +7,7 @@
* "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
* 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
Expand All @@ -21,7 +21,7 @@
import org.antlr.v4.runtime.ParserRuleContext;
import org.kie.dmn.feel.lang.EvaluationContext;
import org.kie.dmn.feel.lang.Type;
import org.kie.dmn.feel.lang.types.BuiltInType;
import org.kie.dmn.feel.util.BuiltInTypeUtils;

public abstract class TypeNode
extends BaseNode {
Expand All @@ -31,12 +31,12 @@ public TypeNode() {
}

public TypeNode(ParserRuleContext ctx) {
super( ctx );
super(ctx);
}

@Override
public Type evaluate(EvaluationContext ctx) {
return BuiltInType.determineTypeFromName( getText() );
return BuiltInTypeUtils.determineTypeFromName(getText());
}

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/**
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
Expand All @@ -18,33 +18,17 @@
*/
package org.kie.dmn.feel.lang.types;

import java.time.Duration;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.OffsetDateTime;
import java.time.OffsetTime;
import java.time.ZonedDateTime;
import java.time.chrono.ChronoPeriod;
import java.time.temporal.ChronoField;
import java.time.temporal.Temporal;
import java.time.temporal.TemporalAccessor;
import java.time.temporal.TemporalQueries;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.Map;

import java.util.function.Function;
import java.util.stream.Collectors;

import org.kie.dmn.api.feel.runtime.events.FEELEvent;
import org.kie.dmn.feel.lang.SimpleType;
import org.kie.dmn.feel.lang.Type;
import org.kie.dmn.feel.marshaller.FEELStringMarshaller;
import org.kie.dmn.feel.runtime.FEELFunction;
import org.kie.dmn.feel.runtime.Range;
import org.kie.dmn.feel.runtime.UnaryTest;
import org.kie.dmn.feel.runtime.custom.ZoneTime;
import org.kie.dmn.feel.util.BuiltInTypeUtils;

public enum BuiltInType implements SimpleType {

Expand All @@ -67,7 +51,7 @@ public enum BuiltInType implements SimpleType {

BuiltInType(String... names) {
this.names = names;
this.symbols = Arrays.asList(names).stream().map(n -> new BuiltInTypeSymbol(n, this)).collect(Collectors.toList());
this.symbols = Arrays.stream(names).map(n -> new BuiltInTypeSymbol(n, this)).collect(Collectors.toList());
}

public String getName() {
Expand All @@ -79,13 +63,13 @@ public String[] getNames() {
}

public Object fromString(String value) {
return FEELStringMarshaller.INSTANCE.unmarshall( this, value );
return FEELStringMarshaller.INSTANCE.unmarshall(this, value);
}

public String toString(Object value) {
return FEELStringMarshaller.INSTANCE.marshall( value );
return FEELStringMarshaller.INSTANCE.marshall(value);
}

public static <T> Function<FEELEvent, T> justNull() {
// TODO we should add the EventListener here somehow?
return t -> null;
Expand All @@ -98,88 +82,19 @@ public Collection<BuiltInTypeSymbol> getSymbols() {
@Override
public String toString() {
return "Type{ " +
names[0] +
" }";
}

public static Type determineTypeFromName( String name ) {
if( name == null ) {
return UNKNOWN;
}
for( BuiltInType t : BuiltInType.values() ) {
for( String n : t.getNames() ) {
if( n.equals( name ) ) {
return t;
}
}
}
return UNKNOWN;
}

public static Type determineTypeFromInstance( Object o ) {
if( o == null ) {
return UNKNOWN;
} else if( o instanceof Number ) {
return NUMBER;
} else if( o instanceof String ) {
return STRING;
} else if( o instanceof LocalDate ) {
return DATE;
} else if( o instanceof LocalTime || o instanceof OffsetTime || o instanceof ZoneTime) {
return TIME;
} else if( o instanceof ZonedDateTime || o instanceof OffsetDateTime || o instanceof LocalDateTime ) {
return DATE_TIME;
} else if (o instanceof Duration || o instanceof ChronoPeriod) {
return DURATION;
} else if( o instanceof Boolean ) {
return BOOLEAN;
} else if( o instanceof UnaryTest ) {
return UNARY_TEST;
} else if( o instanceof Range ) {
return RANGE;
} else if( o instanceof FEELFunction ) {
return FUNCTION;
} else if( o instanceof List ) {
return LIST;
} else if( o instanceof Map ) {
return CONTEXT;
} else if (o instanceof TemporalAccessor) {
// last, determine if it's a FEEL time with TZ
TemporalAccessor ta = (TemporalAccessor) o;
if (!(ta instanceof Temporal) && ta.isSupported(ChronoField.HOUR_OF_DAY)
&& ta.isSupported(ChronoField.MINUTE_OF_HOUR) && ta.isSupported(ChronoField.SECOND_OF_MINUTE)
&& ta.query(TemporalQueries.zone()) != null) {
return TIME;
}
}
return UNKNOWN;
}

public static boolean isInstanceOf( Object o, Type t ) {
if ( o == null ) {
return false; // See FEEL specifications Table 49.
}
if ( t == UNKNOWN ) {
return true;
}
return determineTypeFromInstance( o ) == t;
}

public static boolean isInstanceOf( Object o, String name ) {
return determineTypeFromInstance( o ) == determineTypeFromName( name );
names[0] +
" }";
}

@Override
public boolean isInstanceOf(Object o) {
return isInstanceOf(o, this);
return BuiltInTypeUtils.isInstanceOf(o, this);
}

@Override
public boolean isAssignableValue(Object value) {
if ( value == null ) {
return true; // a null-value can be assigned to any type.
}
return isInstanceOf(value, this);
// a null-value can be assigned to any type.
return value == null || isInstanceOf(value);
}

@Override
Expand Down
Loading
Loading