Skip to content

Commit

Permalink
Merge branch 'development' of github.com:ortus-solutions-private/boxl…
Browse files Browse the repository at this point in the history
…ang into development
  • Loading branch information
jbeers committed Jan 4, 2024
2 parents 1c9e1d6 + ab21deb commit 152ba52
Show file tree
Hide file tree
Showing 142 changed files with 1,777 additions and 1,291 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ public ArrayEach() {
* @argument.maxThreads The maximum number of threads to use when parallel = true
*/
public Object invoke( IBoxContext context, ArgumentsScope arguments ) {
Array actualArray = ArrayCaster.cast( arguments.dereference( Key.array, false ) );
Array actualArray = ArrayCaster.cast( arguments.get( Key.array ) );
Function func = arguments.getAsFunction( Key.callback );

for ( int i = 0; i < actualArray.size(); i++ ) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ public ArrayEvery() {
* @argument.maxThreads The maximum number of threads to use when parallel = true
*/
public Object invoke( IBoxContext context, ArgumentsScope arguments ) {
Array actualArray = ArrayCaster.cast( arguments.dereference( Key.array, false ) );
Array actualArray = ArrayCaster.cast( arguments.get( Key.array ) );
Function func = arguments.getAsFunction( Key.callback );

for ( int i = 0; i < actualArray.size(); i++ ) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ public ArrayPrepend() {
*/
public Object invoke( IBoxContext context, ArgumentsScope arguments ) {
Array actualArray = arguments.getAsArray( Key.array );
actualArray.add( 0, arguments.dereference( Key.value, false ) );
actualArray.add( 0, arguments.get( Key.value ) );
return actualArray;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ public ArrayReduce() {
* @argument.initialValue The initial value of the accumulator
*/
public Object invoke( IBoxContext context, ArgumentsScope arguments ) {
Array actualArray = ArrayCaster.cast( arguments.dereference( Key.array, false ) );
Array actualArray = ArrayCaster.cast( arguments.get( Key.array ) );
Object accumulator = arguments.get( Key.initialValue );
Function func = arguments.getAsFunction( Key.callback );

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ public ArrayReduceRight() {
* @argument.initialValue The initial value of the accumulator
*/
public Object invoke( IBoxContext context, ArgumentsScope arguments ) {
Array actualArray = ArrayCaster.cast( arguments.dereference( Key.array, false ) );
Array actualArray = ArrayCaster.cast( arguments.get( Key.array ) );
Object accumulator = arguments.get( Key.initialValue );
Function func = arguments.getAsFunction( Key.callback );

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,10 +56,10 @@ public ArrayToList() {
* @argument.delimiter The character to use as a separator
*/
public Object invoke( IBoxContext context, ArgumentsScope arguments ) {
Array actualArray = ArrayCaster.cast( arguments.dereference( Key.array, false ) );
Array actualArray = ArrayCaster.cast( arguments.get( Key.array ) );

return actualArray.stream()
.map( StringCaster::cast )
.collect( Collectors.joining( ( ( String ) arguments.dereference( Key.delimiter, false ) ) ) );
.collect( Collectors.joining( ( arguments.getAsString( Key.delimiter ) ) ) );
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/**
* [BoxLang]
*
* Copyright [2023] [Ortus Solutions, Corp]
*
* 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 ortus.boxlang.runtime.bifs.global.system;

import ortus.boxlang.runtime.bifs.BIF;
import ortus.boxlang.runtime.bifs.BoxBIF;
import ortus.boxlang.runtime.context.IBoxContext;
import ortus.boxlang.runtime.scopes.ArgumentsScope;

@BoxBIF
public class GetBoxContext extends BIF {

/**
* Get the current Box Context
*
* @param context The context in which the BIF is being invoked.
* @param arguments Argument scope for the BIF.
*
*/
public Object invoke( IBoxContext context, ArgumentsScope arguments ) {
return context;
}
}
50 changes: 48 additions & 2 deletions src/main/java/ortus/boxlang/runtime/context/BaseBoxContext.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
package ortus.boxlang.runtime.context;

import java.util.ArrayDeque;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

Expand All @@ -33,6 +34,7 @@
import ortus.boxlang.runtime.scopes.Key;
import ortus.boxlang.runtime.services.FunctionService;
import ortus.boxlang.runtime.types.Function;
import ortus.boxlang.runtime.types.Query;
import ortus.boxlang.runtime.types.QueryColumn;
import ortus.boxlang.runtime.types.UDF;
import ortus.boxlang.runtime.types.exceptions.BoxRuntimeException;
Expand Down Expand Up @@ -60,6 +62,8 @@ public class BaseBoxContext implements IBoxContext {
*/
protected ArrayDeque<ITemplateRunnable> templates = new ArrayDeque<>();

protected LinkedHashMap<Query, Integer> queryLoops = new LinkedHashMap<Query, Integer>();

/**
* Creates a new execution context with a bounded execution template and parent context
*
Expand Down Expand Up @@ -473,10 +477,52 @@ public List<ImportDefinition> getCurrentImports() {
*/
public Object unwrapQueryColumn( Object value ) {
if ( value instanceof QueryColumn col ) {
// TODO: get row index from context based on if in cfloop/cfoutput query="..."
return col.getCell( 0 );
return col.getCell( getQueryRow( col.getQuery() ) );
}
return value;
}

/**
* Get the current query row
*
* @param query The query to get the row from
*
* @return The current row
*/
public int getQueryRow( Query query ) {
// If we're not looping over this query, then we're on the first row
if ( !queryLoops.containsKey( query ) ) {
return 0;
}
return queryLoops.get( query );

}

/**
* Register a query loop
*
* @param query The query to register
*/
public void registerQueryLoop( Query query ) {
queryLoops.put( query, 0 );
}

/**
* Unregister a query loop
*
* @param query The query to unregister
*/
public void unregisterQueryLoop( Query query ) {
queryLoops.remove( query );
}

/**
* Increment the query loop
*
* @param query The query to increment
*/
public void incrementQueryLoop( Query query ) {
queryLoops.put( query, queryLoops.get( query ) + 1 );
}

}
31 changes: 31 additions & 0 deletions src/main/java/ortus/boxlang/runtime/context/IBoxContext.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import ortus.boxlang.runtime.runnables.ITemplateRunnable;
import ortus.boxlang.runtime.scopes.IScope;
import ortus.boxlang.runtime.scopes.Key;
import ortus.boxlang.runtime.types.Query;
import ortus.boxlang.runtime.types.UDF;
import ortus.boxlang.runtime.types.exceptions.ScopeNotFoundException;

Expand Down Expand Up @@ -274,4 +275,34 @@ public record ScopeSearchResult( IScope scope, Object value ) {
* @return The unwrapped value
*/
public Object unwrapQueryColumn( Object value );

/**
* Get the current query row
*
* @param query The query to get the row from
*
* @return The current row
*/
public int getQueryRow( Query query );

/**
* Register a query loop
*
* @param query The query to register
*/
public void registerQueryLoop( Query query );

/**
* Unregister a query loop
*
* @param query The query to unregister
*/
public void unregisterQueryLoop( Query query );

/**
* Increment the query loop
*
* @param query The query to increment
*/
public void incrementQueryLoop( Query query );
}
16 changes: 10 additions & 6 deletions src/main/java/ortus/boxlang/runtime/dynamic/IReferenceable.java
Original file line number Diff line number Diff line change
Expand Up @@ -36,16 +36,18 @@ public interface IReferenceable {
/**
* Dereference this object by a key and return the value, or throw exception
*
* @param name The key to dereference
* @param safe Whether to throw an exception if the key is not found
* @param context The context we're executing inside of
* @param name The key to dereference
* @param safe Whether to throw an exception if the key is not found
*
* @return The requested object
*/
public Object dereference( Key name, Boolean safe );
public Object dereference( IBoxContext context, Key name, Boolean safe );

/**
* Dereference this object by a key and invoke the result as an invokable (UDF, java method) using positional arguments
*
* @param context The context we're executing inside of
* @param name The key to dereference
* @param positionalArguments The positional arguments to pass to the invokable
* @param safe Whether to throw an exception if the key is not found
Expand All @@ -57,6 +59,7 @@ public interface IReferenceable {
/**
* Dereference this object by a key and invoke the result as an invokable (UDF, java method) using named arguments
*
* @param context The context we're executing inside of
* @param name The key to dereference
* @param namedArguments The named arguments to pass to the invokable
* @param safe Whether to throw an exception if the key is not found
Expand All @@ -68,11 +71,12 @@ public interface IReferenceable {
/**
* Assign a value to a key in this object
*
* @param name The name of the scope to get
* @param value The value to assign to the scope
* @param context The context we're executing inside of
* @param name The name of the scope to get
* @param value The value to assign to the scope
*
* @return The value that was assigned
*/
public Object assign( Key name, Object value );
public Object assign( IBoxContext context, Key name, Object value );

}
37 changes: 20 additions & 17 deletions src/main/java/ortus/boxlang/runtime/dynamic/Referencer.java
Original file line number Diff line number Diff line change
Expand Up @@ -35,17 +35,18 @@ public class Referencer {
/**
* Used to implement any time an object is dereferenced,
*
* @param object The object to dereference
* @param key The key to dereference
* @param safe Whether to throw an exception if the key is not found
* @param context The context we're executing inside of
* @param object The object to dereference
* @param key The key to dereference
* @param safe Whether to throw an exception if the key is not found
*
* @return The value that was dereferenced
*/
public static Object get( Object object, Key key, Boolean safe ) {
public static Object get( IBoxContext context, Object object, Key key, Boolean safe ) {
if ( safe && object == null ) {
return null;
}
return DynamicJavaInteropService.dereference( object.getClass(), object, key, safe );
return DynamicJavaInteropService.dereference( context, object.getClass(), object, key, safe );
}

/**
Expand Down Expand Up @@ -104,14 +105,15 @@ public static Object getAndInvoke( IBoxContext context, Object object, Key key,
/**
* Used to implement any time an object is assigned to,
*
* @param object The object to dereference
* @param key The key to dereference
* @param value The value to assign
* @param context The context we're executing inside of
* @param object The object to dereference
* @param key The key to dereference
* @param value The value to assign
*
* @return The value that was assigned
*/
public static Object set( Object object, Key key, Object value ) {
return DynamicJavaInteropService.assign( object.getClass(), object, key, value );
public static Object set( IBoxContext context, Object object, Key key, Object value ) {
return DynamicJavaInteropService.assign( context, object.getClass(), object, key, value );
}

/**
Expand All @@ -121,30 +123,31 @@ public static Object set( Object object, Key key, Object value ) {
* An exception will be thrown if any intermediate keys exists, but are not a
* Map.
*
* @param object The object to dereference
* @param value The value to assign
* @param keys The keys to dereference
* @param context The context we're executing inside of
* @param object The object to dereference
* @param value The value to assign
* @param keys The keys to dereference
*
* @return The value that was assigned
*/
public static Object setDeep( Object object, Object value, Key... keys ) {
public static Object setDeep( IBoxContext context, Object object, Object value, Key... keys ) {

for ( int i = 0; i <= keys.length - 1; i++ ) {
Key key = keys[ i ];
// At the final key, just assign our value and we're done
if ( i == keys.length - 1 ) {

set( object, key, value );
set( context, object, key, value );
return value;
}

// For all intermediate keys, check if they exist and are a Struct or Array
Object next = DynamicObject.unWrap( get( object, key, true ) );
Object next = DynamicObject.unWrap( get( context, object, key, true ) );
// If missing, create as a Struct
if ( next == null ) {

next = new Struct();
set( object, key, next );
set( context, object, key, next );
// If it's not null, it needs to be a Map
} else if ( ! ( next instanceof Map || next instanceof Array ) ) {
throw new BoxRuntimeException(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import ortus.boxlang.runtime.interop.DynamicObject;
import ortus.boxlang.runtime.scopes.ArgumentsScope;
import ortus.boxlang.runtime.types.Array;
import ortus.boxlang.runtime.types.QueryColumn;
import ortus.boxlang.runtime.types.exceptions.BoxCastException;

/**
Expand Down Expand Up @@ -101,6 +102,10 @@ public static Array cast( Object object, Boolean fail ) {
return args.asArray();
}

if ( object instanceof QueryColumn col ) {
return col.getColumnDataAsArray();
}

if ( fail ) {
throw new BoxCastException(
String.format( "Can't cast [%s] to a Array.", object.getClass().getName() )
Expand Down
Loading

0 comments on commit 152ba52

Please sign in to comment.