Skip to content

Commit

Permalink
Merge pull request #106 from ortus-boxlang/development
Browse files Browse the repository at this point in the history
1.0.0-Beta13
  • Loading branch information
lmajano authored Sep 6, 2024
2 parents acca7a0 + afd2eb3 commit af3ef8b
Show file tree
Hide file tree
Showing 129 changed files with 2,449 additions and 1,268 deletions.
6 changes: 3 additions & 3 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ dependencies {
testImplementation "org.wiremock:wiremock:3.9.1"
// https://mvnrepository.com/artifact/org.apache.derby/derby
testImplementation 'org.apache.derby:derby:10.17.1.0'
testImplementation 'io.undertow:undertow-core:2.3.16.Final'
testImplementation 'io.undertow:undertow-core:2.3.17.Final'

// Antlr
antlr "org.antlr:antlr4:$antlrVersion"
Expand All @@ -107,9 +107,9 @@ dependencies {
// https://mvnrepository.com/artifact/commons-io/commons-io
implementation "commons-io:commons-io:2.16.1"
// https://mvnrepository.com/artifact/com.github.javaparser/javaparser-symbol-solver-core
implementation 'com.github.javaparser:javaparser-symbol-solver-core:3.26.1'
implementation 'com.github.javaparser:javaparser-symbol-solver-core:3.26.2'
// https://mvnrepository.com/artifact/org.apache.commons/commons-lang3
implementation 'org.apache.commons:commons-lang3:3.16.0'
implementation 'org.apache.commons:commons-lang3:3.17.0'
// https://mvnrepository.com/artifact/org.apache.commons/commons-text
// Many of these classes ( e.g. StringEscapeUtils ) are currently deprecated in commons-lang and others will be moved in the future
implementation 'org.apache.commons:commons-text:1.12.0'
Expand Down
4 changes: 2 additions & 2 deletions gradle.properties
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#Fri Aug 30 16:29:10 UTC 2024
#Fri Aug 30 16:46:29 UTC 2024
antlrVersion=4.13.1
jdkVersion=21
version=1.0.0-beta12
version=1.0.0-beta13
2 changes: 1 addition & 1 deletion src/main/antlr/BoxScriptGrammar.g4
Original file line number Diff line number Diff line change
Expand Up @@ -407,7 +407,7 @@ rethrow: RETHROW
;

// throw Exception;
throw: THROW expression
throw: { isThrow(_input) }? THROW expression
;

/*
Expand Down
2 changes: 1 addition & 1 deletion src/main/antlr/CFScriptGrammar.g4
Original file line number Diff line number Diff line change
Expand Up @@ -392,7 +392,7 @@ rethrow: RETHROW
;

// throw Exception;
throw: THROW expression
throw: { isThrow(_input) }? THROW expression
;

/*
Expand Down
12 changes: 4 additions & 8 deletions src/main/antlr/DocLexer.g4
Original file line number Diff line number Diff line change
@@ -1,15 +1,11 @@



lexer grammar DocLexer;

NAME: [a-zA-Z.0-9]+;
NAME: [a-zA-Z.0-9:]+;

NEWLINE:
'\n' (SPACE? (STAR {_input.LA(1) != '/'}?)+)?
| '\r\n' (SPACE? (STAR {_input.LA(1) != '/'}?)+)?
| '\r' (SPACE? (STAR {_input.LA(1) != '/'}?)+)?
;
'\n' (SPACE? (STAR {_input.LA(1) != '/'}?)+)?
| '\r\n' (SPACE? (STAR {_input.LA(1) != '/'}?)+)?
| '\r' (SPACE? (STAR {_input.LA(1) != '/'}?)+)?;

SPACE: (' ' | '\t')+;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -282,6 +282,7 @@ public static void methodWithContextAndClassLocator( ClassNode classNode,
Type returnType,
boolean isStatic,
Transpiler transpiler,
boolean implicityReturnNull,
Supplier<List<AbstractInsnNode>> supplier ) {
MethodContextTracker tracker = new MethodContextTracker( isStatic );
transpiler.addMethodContextTracker( tracker );
Expand All @@ -302,6 +303,7 @@ public static void methodWithContextAndClassLocator( ClassNode classNode,
Type.getMethodDescriptor( Type.getType( ClassLocator.class ) ),
false );
tracker.storeNewVariable( Opcodes.ASTORE ).nodes().forEach( ( node ) -> node.accept( methodVisitor ) );

// methodVisitor.visitVarInsn( Opcodes.ASTORE, isStatic ? 1 : 2 );
List<AbstractInsnNode> nodes = supplier.get();
if ( !nodes.isEmpty() && ( nodes.get( nodes.size() - 1 ).getOpcode() == Opcodes.POP || nodes.get( nodes.size() - 1 ).getOpcode() == Opcodes.POP2 ) ) {
Expand All @@ -310,6 +312,11 @@ public static void methodWithContextAndClassLocator( ClassNode classNode,
nodes.forEach( node -> node.accept( methodVisitor ) );
}

if ( implicityReturnNull ) {
// push a null onto the stack so that we can return it if there isn't an explicity return
new InsnNode( Opcodes.ACONST_NULL ).accept( methodVisitor );
}

methodVisitor.visitInsn( returnType.getOpcode( Opcodes.IRETURN ) );
methodVisitor.visitMaxs( 0, 0 );

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -262,6 +262,7 @@ public ClassNode transpile( BoxScript boxScript ) throws BoxRuntimeException {
returnType,
false,
this,
false,
() -> AsmHelper.transformBodyExpressions( this, boxScript.getStatements(), TransformerContext.NONE,
returnType == Type.VOID_TYPE ? ReturnValueContext.EMPTY : ReturnValueContext.VALUE_OR_NULL )
);
Expand Down Expand Up @@ -626,12 +627,12 @@ public ClassNode transpile( BoxClass boxClass ) throws BoxRuntimeException {
Type.getType( Key.class ), Type.getType( Map.class ), Type.getType( Boolean.class ) );
AsmHelper.boxClassSupport( classNode, "registerInterface", Type.VOID_TYPE, Type.getType( BoxInterface.class ) );

AsmHelper.methodWithContextAndClassLocator( classNode, "_pseudoConstructor", Type.getType( IBoxContext.class ), Type.VOID_TYPE, false, this,
AsmHelper.methodWithContextAndClassLocator( classNode, "_pseudoConstructor", Type.getType( IBoxContext.class ), Type.VOID_TYPE, false, this, true,
() -> boxClass.getBody().stream().flatMap( statement -> transform( statement, TransformerContext.NONE, ReturnValueContext.EMPTY ).stream() )
.toList()
);

AsmHelper.methodWithContextAndClassLocator( classNode, "staticInitializer", Type.getType( IBoxContext.class ), Type.VOID_TYPE, true, this,
AsmHelper.methodWithContextAndClassLocator( classNode, "staticInitializer", Type.getType( IBoxContext.class ), Type.VOID_TYPE, true, this, true,
List::of
);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ public List<AbstractInsnNode> transform( BoxNode node, TransformerContext contex
Type.getType( BoxSourceType.class ) );

AsmHelper.methodWithContextAndClassLocator( classNode, "_invoke", Type.getType( FunctionBoxContext.class ), Type.getType( Object.class ), false,
transpiler,
transpiler, false,
() -> boxClosure.getBody().getChildren().stream().flatMap( statement -> transpiler.transform( statement, TransformerContext.NONE ).stream() )
.toList() );

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ public List<AbstractInsnNode> transform( BoxNode node, TransformerContext contex
Type.getType( BoxSourceType.class ) );

AsmHelper.methodWithContextAndClassLocator( classNode, "_invoke", Type.getType( FunctionBoxContext.class ), Type.getType( Object.class ), false,
transpiler,
transpiler, false,
() -> boxLambda.getBody().getChildren().stream().flatMap( statement -> transpiler.transform( statement, TransformerContext.NONE ).stream() )
.toList() );

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ public List<AbstractInsnNode> transform( BoxNode node, TransformerContext contex

transpiler.getCurrentMethodContextTracker().ifPresent( tracker -> nodes.addAll( tracker.loadCurrentContext() ) );

nodes.addAll( transpiler.transform( invocation.getObj(), context, returnContext ) );
nodes.addAll( transpiler.transform( invocation.getObj(), context, ReturnValueContext.VALUE ) );

if ( invocation.getUsedDotAccess() ) {
nodes.addAll( transpiler.createKey( ( ( BoxIdentifier ) invocation.getName() ).getName() ) );
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ public List<AbstractInsnNode> transform( BoxNode node, TransformerContext contex
if ( boxReturn.getExpression() == null ) {
nodes.add( new InsnNode( Opcodes.ACONST_NULL ) );
} else {
nodes.addAll( transpiler.transform( boxReturn.getExpression(), TransformerContext.NONE, returnContext ) );
nodes.addAll( transpiler.transform( boxReturn.getExpression(), TransformerContext.NONE, ReturnValueContext.VALUE_OR_NULL ) );
}
nodes.add( new InsnNode( Opcodes.ARETURN ) );
return nodes;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ private Type defineBodyLambdaClass( List<BoxStatement> body ) {
}, Type.getType( Component.ComponentBody.class ) );

AsmHelper.methodWithContextAndClassLocator( classNode, "process", Type.getType( IBoxContext.class ), Type.getType( Component.BodyResult.class ), false,
transpiler,
transpiler, false,
() -> {
List<AbstractInsnNode> nodes = new ArrayList<>();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -134,8 +134,8 @@ public List<AbstractInsnNode> transform( BoxNode node, TransformerContext contex
Type.getType( BoxSourceType.class ) );

AsmHelper.methodWithContextAndClassLocator( classNode, "_invoke", Type.getType( FunctionBoxContext.class ), Type.getType( Object.class ), false,
transpiler,
() -> function.getBody().stream().flatMap( statement -> transpiler.transform( statement, safe, ReturnValueContext.VALUE_OR_NULL ).stream() )
transpiler, true,
() -> function.getBody().stream().flatMap( statement -> transpiler.transform( statement, safe, ReturnValueContext.EMPTY ).stream() )
.toList() );

AsmHelper.complete( classNode, type, methodVisitor -> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,10 +83,6 @@ public List<AbstractInsnNode> transform( BoxNode node, TransformerContext contex
var eVar = tracker.storeNewVariable( Opcodes.ASTORE );
nodes.addAll( eVar.nodes() );

if ( returnValueContext == ReturnValueContext.VALUE_OR_NULL && boxTry.getCatches().size() == 0 ) {
nodes.add( new InsnNode( Opcodes.ACONST_NULL ) );
}

for ( BoxTryCatch catchNode : boxTry.getCatches() ) {
nodes.addAll(
generateCatchBodyNodes( context, returnValueContext, tracker, boxTry, catchNode, finallyStartLabel, finallyEndLabel, eVar.index() )
Expand All @@ -97,9 +93,15 @@ public List<AbstractInsnNode> transform( BoxNode node, TransformerContext contex
null );
transpiler.addTryCatchBlock( catchHandler );

// if we are here none of our catch handlers matched the error so we jump to the finally block
nodes.add( new VarInsnNode( Opcodes.ALOAD, eVar.index() ) );
nodes.add( new JumpInsnNode( Opcodes.GOTO, finallyStartLabel ) );
// if we are here none of our catch handlers matched the error so we inline another finally block
if ( boxTry.getFinallyBody().size() == 0 ) {
nodes.add( new InsnNode( Opcodes.ACONST_NULL ) );
if ( returnValueContext != ReturnValueContext.VALUE_OR_NULL ) {
nodes.add( new InsnNode( Opcodes.POP ) );
}
}
nodes.addAll( AsmHelper.transformBodyExpressions( transpiler, boxTry.getFinallyBody(), context, returnValueContext ) );
nodes.add( new JumpInsnNode( Opcodes.GOTO, finallyEndLabel ) );
}

TryCatchBlockNode catchHandler = new TryCatchBlockNode( tryStartLabel, tryEndLabel, finallyStartLabel,
Expand Down Expand Up @@ -133,8 +135,11 @@ private List<AbstractInsnNode> generateBodyNodesWithInlinedFinally(
Supplier<AbstractInsnNode> inBetween ) {
List<AbstractInsnNode> nodes = new ArrayList<AbstractInsnNode>();

if ( returnValueContext == ReturnValueContext.VALUE_OR_NULL && codeBody.size() == 0 && finallyBody.size() == 0 ) {
if ( codeBody.size() == 0 && finallyBody.size() == 0 ) {
nodes.add( new InsnNode( Opcodes.ACONST_NULL ) );
if ( returnValueContext != ReturnValueContext.VALUE_OR_NULL ) {
nodes.add( new InsnNode( Opcodes.POP ) );
}
}

nodes.addAll( AsmHelper.transformBodyExpressions(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -771,9 +771,9 @@ public BoxNode visit( BoxComponent node ) {
attr.getKey().setValue( attrMap.get( key ) );
}
}

attrs.stream().forEach( attr -> {
if ( attr.getKey().getValue().equalsIgnoreCase( "attributeCollection" ) ) {
node.addComment( new BoxSingleLineComment( "Transpiler workaround for runtime transpilation of attributeCollection", null, null ) );

List<BoxExpression> keyList = attrMap.keySet().stream()
.flatMap( k -> Stream.of( new BoxStringLiteral( k, null, null ), new BoxStringLiteral( attrMap.get( k ), null, null ) ) )
Expand Down Expand Up @@ -807,7 +807,6 @@ public BoxNode visit( BoxComponent node ) {
}
} );
}
node.addComment( new BoxSingleLineComment( "Transpiler workaround for runtime transpilation of attributeCollection", null, null ) );
return super.visit( node );
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ public class ${classname} extends BoxInterface {
private static Map<Key, Function> defaultMethods = new LinkedHashMap<>();
private static ${classname} instance;
private static Key name = ${boxInterfacename};
private static BoxInterface _super = null;
private static List<BoxInterface> _supers = new ArrayList();
private static StaticScope staticScope;
private ${classname}() {
Expand Down Expand Up @@ -224,12 +224,12 @@ public Key getName() {
return this.name;
}
public void _setSuper( BoxInterface _super ) {
this._super = _super;
public void _addSuper( BoxInterface _super ) {
this._supers.add( _super );
}
public BoxInterface getSuper() {
return this._super;
public List<BoxInterface> getSupers() {
return this._supers;
}
// Instance method required to get from IClassRunnable
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ public Node transform( BoxNode node, TransformerContext context ) throws Illegal
Expression expr2 = ( Expression ) transpiler.transform( ( BoxNode ) boxNew.getArguments().get( i ), context );
values.put( "arg" + i, expr2.toString() );
}
String template = "classLocator.load(context,\"${prefix}\".concat( StringCaster.cast(${expr})),imports).invokeConstructor( ${contextName}, "
String template = "classLocator.load(${contextName},\"${prefix}\".concat( StringCaster.cast(${expr})),imports).invokeConstructor( ${contextName}, "
+ generateArguments( boxNew.getArguments() ) + " ).unWrapBoxLangClass()";
Node javaStmt = parseExpression( template, values );
// logger.trace( node.getSourceText() + " -> " + javaStmt );
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ public Node transform( BoxNode node, TransformerContext context ) throws Illegal
expr = new NullLiteralExpr();
}

if ( message != null ) {
if ( message != null || type != null || detail != null || errorcode != null || extendedinfo != null ) {
Expression jType = new NullLiteralExpr();
Expression jMessage = new NullLiteralExpr();
Expression jDetail = new NullLiteralExpr();
Expand Down
14 changes: 14 additions & 0 deletions src/main/java/ortus/boxlang/compiler/parser/BoxParserControl.java
Original file line number Diff line number Diff line change
Expand Up @@ -196,4 +196,18 @@ protected boolean isAssignmentModifier( TokenStream input ) {
int thisType = input.LT( 1 ).getType();
return ( thisType == VAR || thisType == FINAL || thisType == STATIC ) && identifiers.contains( input.LT( 2 ).getType() );
}

/**
* Provides a gate for the [throw expr] rule if the token after throw is `(` don't match since we'll assume it's the throw() BIF.
* This DOES rule out code like `throw (new Exception())` but that's a rare case.
*
* @param input the token input stream
*
* @return true if this should be seen as a throw
*/
protected boolean isThrow( TokenStream input ) {
int thisType = input.LT( 1 ).getType();
int nextType = input.LT( 2 ).getType();
return thisType == THROW && nextType != LPAREN;
}
}
14 changes: 14 additions & 0 deletions src/main/java/ortus/boxlang/compiler/parser/CFParserControl.java
Original file line number Diff line number Diff line change
Expand Up @@ -197,4 +197,18 @@ protected boolean isAssignmentModifier( TokenStream input ) {
int thisType = input.LT( 1 ).getType();
return ( thisType == VAR || thisType == FINAL || thisType == STATIC ) && identifiers.contains( input.LT( 2 ).getType() );
}

/**
* Provides a gate for the [throw expr] rule if the token after throw is `(` don't match since we'll assume it's the throw() BIF.
* This DOES rule out code like `throw (new Exception())` but that's a rare case.
*
* @param input the token input stream
*
* @return true if this should be seen as a throw
*/
protected boolean isThrow( TokenStream input ) {
int thisType = input.LT( 1 ).getType();
int nextType = input.LT( 2 ).getType();
return thisType == THROW && nextType != LPAREN;
}
}
6 changes: 6 additions & 0 deletions src/main/java/ortus/boxlang/compiler/parser/Parser.java
Original file line number Diff line number Diff line change
Expand Up @@ -269,6 +269,12 @@ private static BoxSourceType guessClassType( File file, Charset charset ) throws
if ( line.startsWith( "component" ) || line.startsWith( "interface" ) ) {
return BoxSourceType.CFSCRIPT;
}
if ( line.startsWith( "abstract" ) && line.contains( "component" ) ) {
return BoxSourceType.CFSCRIPT;
}
if ( line.startsWith( "final" ) && line.contains( "component" ) ) {
return BoxSourceType.CFSCRIPT;
}
if ( line.startsWith( "<cfcomponent" ) || line.startsWith( "<cfinterface" ) || line.startsWith( "<cfscript" ) ) {
return BoxSourceType.CFTEMPLATE;
}
Expand Down
Loading

0 comments on commit af3ef8b

Please sign in to comment.