From bb1379222f289d74f748500143929a20f0ae6535 Mon Sep 17 00:00:00 2001 From: Ben Sherman Date: Sun, 26 Apr 2026 08:40:33 -0500 Subject: [PATCH] Fix runtime type reflection in nf-lang Signed-off-by: Ben Sherman --- .../nextflow/plugin/spec/ConfigSpec.groovy | 21 ++-- .../nextflow/plugin/spec/FunctionSpec.groovy | 24 ++--- .../nextflow/processor/TaskProcessor.groovy | 2 +- .../groovy/nextflow/script/ParamsDsl.groovy | 2 +- .../groovy/nextflow/script/TypeDef.groovy | 2 + .../plugin/spec/PluginSpecTest.groovy | 102 ++++++++++-------- .../nextflow/script/ScriptTypesTest.groovy | 47 ++++++++ .../nextflow/config/control/ConfigParser.java | 2 +- .../java/nextflow/config/spec/SpecNode.java | 33 +++--- .../control/ProcessToGroovyVisitorV2.java | 28 +---- .../nextflow/script/control/ScriptParser.java | 2 +- .../nextflow/script/{types => dsl}/Types.java | 100 ++++++++++------- .../nextflow/script/formatter/Formatter.java | 4 +- .../formatter/ScriptFormatterTest.groovy | 2 +- 14 files changed, 221 insertions(+), 150 deletions(-) rename modules/nf-lang/src/main/java/nextflow/script/{types => dsl}/Types.java (61%) diff --git a/modules/nextflow/src/main/groovy/nextflow/plugin/spec/ConfigSpec.groovy b/modules/nextflow/src/main/groovy/nextflow/plugin/spec/ConfigSpec.groovy index 3e951bee9b..c4d5cc5f9d 100644 --- a/modules/nextflow/src/main/groovy/nextflow/plugin/spec/ConfigSpec.groovy +++ b/modules/nextflow/src/main/groovy/nextflow/plugin/spec/ConfigSpec.groovy @@ -15,10 +15,12 @@ */ package nextflow.plugin.spec +import java.lang.reflect.ParameterizedType +import java.lang.reflect.Type + import groovy.transform.CompileStatic import nextflow.config.spec.SpecNode -import nextflow.script.types.Types -import org.codehaus.groovy.ast.ClassNode +import nextflow.script.dsl.Types /** * Generate specs for config scopes. @@ -44,7 +46,7 @@ class ConfigSpec { private static Map fromOption(SpecNode.Option node, String name) { final description = node.description().stripIndent(true).trim() - final types = node.types().collect { t -> fromType(new ClassNode(t)) } + final types = node.types().collect { t -> fromType(t) } return [ type: 'ConfigOption', @@ -89,14 +91,13 @@ class ConfigSpec { ] } - private static Object fromType(ClassNode cn) { - final name = Types.getName(cn.getTypeClass()) - if( !cn.isGenericsPlaceHolder() && cn.getGenericsTypes() != null ) { - final typeArguments = cn.getGenericsTypes().collect { gt -> fromType(gt.getType()) } + private static Object fromType(Type type) { + if( type instanceof ParameterizedType ) { + final name = Types.getName(type.getRawType()) + final typeArguments = type.getActualTypeArguments().collect { t -> fromType(t) } return [ name: name, typeArguments: typeArguments ] } - else { - return name - } + + return Types.getName(type) } } diff --git a/modules/nextflow/src/main/groovy/nextflow/plugin/spec/FunctionSpec.groovy b/modules/nextflow/src/main/groovy/nextflow/plugin/spec/FunctionSpec.groovy index b925613d19..5be469a3c2 100644 --- a/modules/nextflow/src/main/groovy/nextflow/plugin/spec/FunctionSpec.groovy +++ b/modules/nextflow/src/main/groovy/nextflow/plugin/spec/FunctionSpec.groovy @@ -16,11 +16,12 @@ package nextflow.plugin.spec import java.lang.reflect.Method +import java.lang.reflect.ParameterizedType +import java.lang.reflect.Type import groovy.transform.CompileStatic import nextflow.script.dsl.Description -import nextflow.script.types.Types -import org.codehaus.groovy.ast.ClassNode +import nextflow.script.dsl.Types /** * Generate specs for functions, channel factories, and operators. @@ -37,7 +38,7 @@ class FunctionSpec { final parameters = method.getParameters().collect { param -> [ name: param.getName(), - type: fromType(param.getType()) + type: fromType(param.getParameterizedType()) ] } @@ -52,18 +53,13 @@ class FunctionSpec { ] } - private static Object fromType(Class c) { - return fromType(new ClassNode(c)) - } - - private static Object fromType(ClassNode cn) { - final name = Types.getName(cn.getTypeClass()) - if( !cn.isGenericsPlaceHolder() && cn.getGenericsTypes() != null ) { - final typeArguments = cn.getGenericsTypes().collect { gt -> fromType(gt.getType()) } + private static Object fromType(Type type) { + if( type instanceof ParameterizedType ) { + final name = Types.getName(type.getRawType()) + final typeArguments = type.getActualTypeArguments().collect { t -> fromType(t) } return [ name: name, typeArguments: typeArguments ] } - else { - return name - } + + return Types.getName(type) } } diff --git a/modules/nextflow/src/main/groovy/nextflow/processor/TaskProcessor.groovy b/modules/nextflow/src/main/groovy/nextflow/processor/TaskProcessor.groovy index 15cb435680..0fe47e782c 100644 --- a/modules/nextflow/src/main/groovy/nextflow/processor/TaskProcessor.groovy +++ b/modules/nextflow/src/main/groovy/nextflow/processor/TaskProcessor.groovy @@ -75,6 +75,7 @@ import nextflow.script.ProcessConfigV2 import nextflow.script.ScriptMeta import nextflow.script.ScriptType import nextflow.script.bundle.ResourcesBundle +import nextflow.script.dsl.Types import nextflow.script.params.BaseOutParam import nextflow.script.params.CmdEvalParam import nextflow.script.params.DefaultOutParam @@ -97,7 +98,6 @@ import nextflow.script.params.v2.ProcessInput import nextflow.script.params.v2.ProcessTupleInput import nextflow.script.types.Record import nextflow.script.types.Tuple -import nextflow.script.types.Types import nextflow.trace.TraceRecord import nextflow.util.Escape import nextflow.util.HashBuilder diff --git a/modules/nextflow/src/main/groovy/nextflow/script/ParamsDsl.groovy b/modules/nextflow/src/main/groovy/nextflow/script/ParamsDsl.groovy index 079e33ed01..68f28def61 100644 --- a/modules/nextflow/src/main/groovy/nextflow/script/ParamsDsl.groovy +++ b/modules/nextflow/src/main/groovy/nextflow/script/ParamsDsl.groovy @@ -26,8 +26,8 @@ import groovy.util.logging.Slf4j import nextflow.Session import nextflow.file.FileHelper import nextflow.exception.ScriptRuntimeException +import nextflow.script.dsl.Types import nextflow.script.types.Bag -import nextflow.script.types.Types import nextflow.splitter.CsvSplitter import nextflow.util.ArrayBag import nextflow.util.Duration diff --git a/modules/nextflow/src/main/groovy/nextflow/script/TypeDef.groovy b/modules/nextflow/src/main/groovy/nextflow/script/TypeDef.groovy index 40f9170994..b91e127fe3 100644 --- a/modules/nextflow/src/main/groovy/nextflow/script/TypeDef.groovy +++ b/modules/nextflow/src/main/groovy/nextflow/script/TypeDef.groovy @@ -39,6 +39,8 @@ class TypeDef extends ComponentDef { this.alias = alias } + Class getTarget() { target } + @Override String getType() { 'type' } diff --git a/modules/nextflow/src/test/groovy/nextflow/plugin/spec/PluginSpecTest.groovy b/modules/nextflow/src/test/groovy/nextflow/plugin/spec/PluginSpecTest.groovy index eede6284f2..bac39b9544 100644 --- a/modules/nextflow/src/test/groovy/nextflow/plugin/spec/PluginSpecTest.groovy +++ b/modules/nextflow/src/test/groovy/nextflow/plugin/spec/PluginSpecTest.groovy @@ -47,57 +47,65 @@ class PluginSpecTest extends Specification { expect: definitions.size() == 4 and: - definitions[0] == [ - type: 'ConfigScope', - spec: [ - name: 'hello', - description: 'The `hello` scope controls the behavior of the `nf-hello` plugin.', - children: [ - [ - type: 'ConfigOption', - spec: [ - name: 'message', - description: 'Message to print to standard output when the plugin is enabled.', - type: 'String', - additionalTypes: [] - ] - ] + definitions[0].type == 'ConfigScope' + definitions[0].spec.name == 'hello' + definitions[0].spec.description == 'The `hello` scope controls the behavior of the `nf-hello` plugin.' + definitions[0].spec.children.sort { it.spec.name } == [ + [ + type: 'ConfigOption', + spec: [ + name: 'message', + description: 'Message to print to standard output when the plugin is enabled.', + type: 'String', + additionalTypes: [] + ] + ], + [ + type: 'ConfigOption', + spec: [ + name: 'names', + description: 'Names to address when the plugin is enabled.', + type: [ + name: 'List', + typeArguments: [ 'String' ] + ], + additionalTypes: [] ] ] ] - definitions[1] == [ - type: 'Factory', - spec: [ - name: 'helloFactory', - description: null, - returnType: 'DataflowWriteChannel', - parameters: [] - ] + and: + definitions[1].type == 'Factory' + definitions[1].spec == [ + name: 'helloFactory', + description: null, + returnType: 'DataflowWriteChannel', + parameters: [] ] - definitions[2] == [ - type: 'Operator', - spec: [ - name: 'helloOperator', - description: null, - returnType: 'DataflowWriteChannel', - parameters: [ - [ - name: 'arg0', - type: 'DataflowReadChannel' - ] + and: + definitions[2].type == 'Operator' + definitions[2].spec == [ + name: 'helloOperator', + description: null, + returnType: 'DataflowWriteChannel', + parameters: [ + [ + name: 'arg0', + type: 'DataflowReadChannel' ] ] ] - definitions[3] == [ - type: 'Function', - spec: [ - name: 'sayHello', - description: 'Say hello to the given targets', - returnType: 'void', - parameters: [ - [ - name: 'arg0', - type: 'List' + and: + definitions[3].type == 'Function' + definitions[3].spec == [ + name: 'sayHello', + description: 'Say hello to the given targets', + returnType: 'void', + parameters: [ + [ + name: 'arg0', + type: [ + name: 'List', + typeArguments: [ 'String' ] ] ] ] @@ -115,6 +123,12 @@ class TestConfig implements ConfigScope { Message to print to standard output when the plugin is enabled. ''') String message + + @ConfigOption + @Description(''' + Names to address when the plugin is enabled. + ''') + List names } diff --git a/modules/nextflow/src/test/groovy/nextflow/script/ScriptTypesTest.groovy b/modules/nextflow/src/test/groovy/nextflow/script/ScriptTypesTest.groovy index 8d607ddbd6..3aff984d68 100644 --- a/modules/nextflow/src/test/groovy/nextflow/script/ScriptTypesTest.groovy +++ b/modules/nextflow/src/test/groovy/nextflow/script/ScriptTypesTest.groovy @@ -16,7 +16,9 @@ package nextflow.script +import java.lang.reflect.ParameterizedType import java.nio.file.Files +import java.nio.file.Path import nextflow.exception.ScriptCompilationException import test.Dsl2Spec @@ -195,4 +197,49 @@ class ScriptTypesTest extends Dsl2Spec { cleanup: folder?.deleteDir() } + + def 'should expose type annotations via reflection'() { + when: + def script = loadScript( + '''\ + record Sample { + id: String + reads: List + } + ''', + module: true + ) + def meta = ScriptMeta.get(script) + def typeDef = meta.getComponent('Sample') as TypeDef + def type = typeDef.getTarget() + then: + type.getField('id').getType() == String + type.getField('id').getGenericType() instanceof Class + type.getField('id').getGenericType() == String + type.getField('reads').getType() == List + type.getField('reads').getGenericType() instanceof ParameterizedType + type.getField('reads').getGenericType().getRawType() == List + type.getField('reads').getGenericType().getActualTypeArguments()[0] instanceof Class + type.getField('reads').getGenericType().getActualTypeArguments()[0] == Path + + when: + script = loadScript( + '''\ + def greet(message: String, names: List) { + } + ''', + module: true + ) + def method = script.getClass().getDeclaredMethods().find { m -> m.name == 'greet' } + def params = method.getParameters() + then: + params[0].getType() == String + params[0].getParameterizedType() instanceof Class + params[0].getParameterizedType() == String + params[1].getType() == List + params[1].getParameterizedType() instanceof ParameterizedType + params[1].getParameterizedType().getRawType() == List + params[1].getParameterizedType().getActualTypeArguments()[0] instanceof Class + params[1].getParameterizedType().getActualTypeArguments()[0] == String + } } diff --git a/modules/nf-lang/src/main/java/nextflow/config/control/ConfigParser.java b/modules/nf-lang/src/main/java/nextflow/config/control/ConfigParser.java index 507a9a5bb0..c0d993c611 100644 --- a/modules/nf-lang/src/main/java/nextflow/config/control/ConfigParser.java +++ b/modules/nf-lang/src/main/java/nextflow/config/control/ConfigParser.java @@ -21,7 +21,7 @@ import nextflow.config.parser.ConfigParserPluginFactory; import nextflow.script.control.Compiler; import nextflow.script.control.LazyErrorCollector; -import nextflow.script.types.Types; +import nextflow.script.dsl.Types; import org.codehaus.groovy.control.CompilerConfiguration; import org.codehaus.groovy.control.SourceUnit; import org.codehaus.groovy.control.messages.WarningMessage; diff --git a/modules/nf-lang/src/main/java/nextflow/config/spec/SpecNode.java b/modules/nf-lang/src/main/java/nextflow/config/spec/SpecNode.java index 05096bc12a..ba9057699b 100644 --- a/modules/nf-lang/src/main/java/nextflow/config/spec/SpecNode.java +++ b/modules/nf-lang/src/main/java/nextflow/config/spec/SpecNode.java @@ -19,6 +19,7 @@ import java.lang.reflect.Field; import java.lang.reflect.Method; import java.lang.reflect.ParameterizedType; +import java.lang.reflect.Type; import java.util.ArrayList; import java.util.HashMap; import java.util.List; @@ -109,10 +110,10 @@ private static String annotatedDescription(AnnotatedElement el, String defaultVa return annot != null ? annot.value() : defaultValue; } - private static List optionTypes(Field field) { - var result = new ArrayList(); + private static List optionTypes(Field field) { + var result = new ArrayList(); // use the field type - result.add(field.getType()); + result.add(field.getGenericType()); // append types from ConfigOption annotation if specified var annot = field.getAnnotation(ConfigOption.class); if( annot != null ) { @@ -122,6 +123,14 @@ private static List optionTypes(Field field) { return result; } + private static Class rawType(Type type) { + if( type instanceof Class c ) + return c; + if( type instanceof ParameterizedType pt ) + return (Class) pt.getRawType(); + throw new IllegalStateException(); + } + /** * Models a config option that is defined through a DSL * instead of an assignment (i.e. `plugins`). @@ -136,7 +145,7 @@ public static record DslOption( */ public static record Option( String description, - List types + List types ) implements SpecNode {} /** @@ -212,23 +221,23 @@ public static Scope of(Class scope, String description) { var children = new HashMap(); for( var field : scope.getDeclaredFields() ) { var name = field.getName(); - var type = field.getType(); + var type = field.getGenericType(); + var rawType = rawType(type); var desc = annotatedDescription(field, description); var placeholderName = field.getAnnotation(PlaceholderName.class); // fields annotated with @ConfigOption are config options if( field.getAnnotation(ConfigOption.class) != null ) { - if( DslScope.class.isAssignableFrom(type) ) - children.put(name, new DslOption(desc, type)); + if( DslScope.class.isAssignableFrom(rawType) ) + children.put(name, new DslOption(desc, rawType)); else children.put(name, new Option(desc, optionTypes(field))); } - // fields of type ConfigScope are nested config scopes - else if( ConfigScope.class.isAssignableFrom(type) ) { - children.put(name, Scope.of((Class) type, desc)); + // fields of rawType ConfigScope are nested config scopes + else if( ConfigScope.class.isAssignableFrom(rawType) ) { + children.put(name, Scope.of((Class) rawType, desc)); } // fields of type Map are placeholder scopes - else if( Map.class.isAssignableFrom(type) && placeholderName != null ) { - var pt = (ParameterizedType)field.getGenericType(); + else if( Map.class.isAssignableFrom(rawType) && type instanceof ParameterizedType pt && placeholderName != null ) { var valueType = (Class)pt.getActualTypeArguments()[1]; children.put(name, new Placeholder(desc, placeholderName.value(), Scope.of(valueType, desc))); } diff --git a/modules/nf-lang/src/main/java/nextflow/script/control/ProcessToGroovyVisitorV2.java b/modules/nf-lang/src/main/java/nextflow/script/control/ProcessToGroovyVisitorV2.java index 6d30b179be..9c032dc65b 100644 --- a/modules/nf-lang/src/main/java/nextflow/script/control/ProcessToGroovyVisitorV2.java +++ b/modules/nf-lang/src/main/java/nextflow/script/control/ProcessToGroovyVisitorV2.java @@ -161,14 +161,13 @@ else if( isRecordType(cn) ) { private static boolean isPathType(ClassNode cn) { if( !cn.isResolved() ) return false; - var tn = new TypeNode(cn); - var type = tn.type; - if( Path.class.isAssignableFrom(type) ) { + var clazz = cn.getTypeClass(); + if( Path.class.isAssignableFrom(clazz) ) { return true; } - if( Collection.class.isAssignableFrom(type) && tn.genericTypes != null ) { - var genericType = tn.genericTypes.get(0); - return Path.class.isAssignableFrom(genericType); + if( Collection.class.isAssignableFrom(clazz) && cn.isUsingGenerics() ) { + var elementType = cn.getGenericsTypes()[0].getType(); + return Path.class.isAssignableFrom(elementType.getTypeClass()); } return false; } @@ -177,23 +176,6 @@ private static boolean isRecordType(ClassNode cn) { return cn.redirect() instanceof RecordNode; } - private static class TypeNode { - final Class type; - final List genericTypes; - - public TypeNode(ClassNode cn) { - this.type = cn.getTypeClass(); - if( cn.isUsingGenerics() ) { - this.genericTypes = Arrays.stream(cn.getGenericsTypes()) - .map(el -> el.getType().getTypeClass()) - .toList(); - } - else { - this.genericTypes = null; - } - } - } - private void visitProcessUnstagers(Statement outputs, ProcessUnstageVisitor visitor) { for( var output : asBlockStatements(outputs) ) visitor.visit(output); diff --git a/modules/nf-lang/src/main/java/nextflow/script/control/ScriptParser.java b/modules/nf-lang/src/main/java/nextflow/script/control/ScriptParser.java index ea70bdb2b4..bb8e178a65 100644 --- a/modules/nf-lang/src/main/java/nextflow/script/control/ScriptParser.java +++ b/modules/nf-lang/src/main/java/nextflow/script/control/ScriptParser.java @@ -21,8 +21,8 @@ import java.util.Collections; import groovy.lang.GroovyClassLoader; +import nextflow.script.dsl.Types; import nextflow.script.parser.ScriptParserPluginFactory; -import nextflow.script.types.Types; import org.codehaus.groovy.control.CompilerConfiguration; import org.codehaus.groovy.control.SourceUnit; import org.codehaus.groovy.control.messages.WarningMessage; diff --git a/modules/nf-lang/src/main/java/nextflow/script/types/Types.java b/modules/nf-lang/src/main/java/nextflow/script/dsl/Types.java similarity index 61% rename from modules/nf-lang/src/main/java/nextflow/script/types/Types.java rename to modules/nf-lang/src/main/java/nextflow/script/dsl/Types.java index beeffde8b5..c5bb660bad 100644 --- a/modules/nf-lang/src/main/java/nextflow/script/types/Types.java +++ b/modules/nf-lang/src/main/java/nextflow/script/dsl/Types.java @@ -13,14 +13,14 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package nextflow.script.types; +package nextflow.script.dsl; -import java.nio.file.Path; +import java.lang.reflect.ParameterizedType; +import java.lang.reflect.Type; import java.util.List; import java.util.Map; import nextflow.script.ast.ASTNodeMarker; -import nextflow.script.dsl.Namespace; import org.codehaus.groovy.GroovyBugError; import org.codehaus.groovy.ast.ClassHelper; import org.codehaus.groovy.ast.ClassNode; @@ -35,19 +35,19 @@ public class Types { public static final List DEFAULT_SCRIPT_IMPORTS = List.of( - ClassHelper.makeCached(Bag.class), - ClassHelper.makeCached(Channel.class), - ClassHelper.makeCached(Duration.class), - ClassHelper.makeCached(MemoryUnit.class), - ClassHelper.makeCached(Path.class), - ClassHelper.makeCached(Value.class), - ClassHelper.makeCached(VersionNumber.class) + ClassHelper.makeCached(nextflow.script.types.Bag.class), + ClassHelper.makeCached(nextflow.script.types.Channel.class), + ClassHelper.makeCached(nextflow.script.types.Duration.class), + ClassHelper.makeCached(nextflow.script.types.MemoryUnit.class), + ClassHelper.makeCached(java.nio.file.Path.class), + ClassHelper.makeCached(nextflow.script.types.Value.class), + ClassHelper.makeCached(nextflow.script.types.VersionNumber.class) ); public static final List DEFAULT_CONFIG_IMPORTS = List.of( - ClassHelper.makeCached(Bag.class), - ClassHelper.makeCached(Duration.class), - ClassHelper.makeCached(MemoryUnit.class) + ClassHelper.makeCached(nextflow.script.types.Bag.class), + ClassHelper.makeCached(nextflow.script.types.Duration.class), + ClassHelper.makeCached(nextflow.script.types.MemoryUnit.class) ); /** @@ -92,27 +92,27 @@ public static String getName(ClassNode type) { private static String closureName(ClassNode type) { var mn = ClassHelper.findSAM(type); var spec = GenericsUtils.extractPlaceholders(type); - var builder = new StringBuilder(); + var sb = new StringBuilder(); var params = mn.getParameters(); - builder.append('('); + sb.append('('); for( int i = 0; i < params.length; i++ ) { if( i > 0 ) - builder.append(", "); + sb.append(", "); var paramType = specificType(params[i].getType(), spec); - builder.append(getName(paramType)); + sb.append(getName(paramType)); } - builder.append(')'); + sb.append(')'); var returnType = specificType(mn.getReturnType(), spec); - builder.append(" -> "); - builder.append( + sb.append(" -> "); + sb.append( ClassHelper.VOID_TYPE.equals(returnType) ? "()" : getName(returnType) ); - return builder.toString(); + return sb.toString(); } private static ClassNode specificType(ClassNode type, Map spec) { @@ -123,50 +123,70 @@ private static ClassNode specificType(ClassNode type, Map'); + sb.append('<'); + genericsTypeNames(type.getGenericsTypes(), sb); + sb.append('>'); } if( type.getNodeMetaData(ASTNodeMarker.NULLABLE) != null ) - builder.append('?'); + sb.append('?'); - return builder.toString(); + return sb.toString(); } - private static void genericsTypeNames(GenericsType[] genericsTypes, StringBuilder builder) { + private static void genericsTypeNames(GenericsType[] genericsTypes, StringBuilder sb) { for( int i = 0; i < genericsTypes.length; i++ ) { if( i > 0 ) - builder.append(", "); - builder.append(getName(genericsTypes[i].getType())); + sb.append(", "); + sb.append(getName(genericsTypes[i].getType())); } } - public static String getName(Class type) { + public static String getName(Type type) { + return + type instanceof Class c ? getName(c) : + type instanceof ParameterizedType pt ? getName(pt) : + getName(type.getTypeName()); + } + + private static String getName(Class type) { return getName(type.getSimpleName()); } + private static String getName(ParameterizedType pt) { + var sb = new StringBuilder(); + sb.append(getName(pt.getRawType())); + sb.append('<'); + for( int i = 0; i < pt.getActualTypeArguments().length; i++ ) { + if( i > 0 ) + sb.append(", "); + sb.append(getName(pt.getActualTypeArguments()[i])); + } + sb.append('>'); + return sb.toString(); + } + public static String getName(String name) { if( "Object".equals(name) ) return "?"; diff --git a/modules/nf-lang/src/main/java/nextflow/script/formatter/Formatter.java b/modules/nf-lang/src/main/java/nextflow/script/formatter/Formatter.java index be78b29d7e..d1206edd9a 100644 --- a/modules/nf-lang/src/main/java/nextflow/script/formatter/Formatter.java +++ b/modules/nf-lang/src/main/java/nextflow/script/formatter/Formatter.java @@ -285,7 +285,7 @@ public void visitMethodCallExpression(MethodCallExpression node) { visit(receiver); if( inWrappedMethodChain ) { incIndent(); - if( !nextflow.script.types.Types.isNamespace(receiver.getType()) ) { + if( !nextflow.script.dsl.Types.isNamespace(receiver.getType()) ) { appendNewLine(); appendIndent(); } @@ -636,7 +636,7 @@ public void visitTypeAnnotation(ClassNode type) { if( isLegacyType(type) ) append(type.getNodeMetaData(ASTNodeMarker.LEGACY_TYPE)); else - append(nextflow.script.types.Types.getName(type)); + append(nextflow.script.dsl.Types.getName(type)); } @Override diff --git a/modules/nf-lang/src/test/groovy/nextflow/script/formatter/ScriptFormatterTest.groovy b/modules/nf-lang/src/test/groovy/nextflow/script/formatter/ScriptFormatterTest.groovy index d79444d357..ec4d8a74dc 100644 --- a/modules/nf-lang/src/test/groovy/nextflow/script/formatter/ScriptFormatterTest.groovy +++ b/modules/nf-lang/src/test/groovy/nextflow/script/formatter/ScriptFormatterTest.groovy @@ -18,7 +18,7 @@ package nextflow.script.formatter import nextflow.script.control.ScriptParser import nextflow.script.control.ScriptResolveVisitor -import nextflow.script.types.Types +import nextflow.script.dsl.Types import spock.lang.Shared import spock.lang.Specification import test.TestUtils