2
2
*/
3
3
package dxWDL
4
4
5
- import java .nio .file .{Files , Paths , Path }
6
5
import net .jcazevedo .moultingyaml ._
7
- import net .jcazevedo .moultingyaml .DefaultYamlProtocol ._
8
6
import scala .util .{Failure , Success , Try }
9
- import spray .json ._
10
- import wdl4s ._
11
- import wdl4s .AstTools
12
- import wdl4s .AstTools .EnhancedAstNode
13
- import wdl4s .expression ._
14
- import wdl4s .parser .WdlParser .{Ast , AstNode , Terminal }
15
- import wdl4s .types ._
16
- import wdl4s .values ._
17
- import wdl4s .WdlExpression .AstForExpressions
7
+ import wdl4s .wdl ._
8
+ import wdl4s .wdl .AstTools
9
+ import wdl4s .wdl .AstTools .EnhancedAstNode
10
+ import wdl4s .wdl .expression ._
11
+ import wdl4s .parser .WdlParser .{Ast , Terminal }
12
+ import wdl4s .wdl .types ._
13
+ import wdl4s .wdl .values ._
14
+ import wdl4s .wdl .WdlExpression .AstForExpressions
18
15
19
16
case class CompilerIR (gWorkflowOutputs : Option [Seq [WorkflowOutput ]],
20
17
destination : String ,
@@ -85,7 +82,7 @@ task Add {
85
82
Int result
86
83
}
87
84
*/
88
- def genAppletStub (applet : IR .Applet , scope : Scope ) : Task = {
85
+ def genAppletStub (applet : IR .Applet , scope : Scope ) : WdlTask = {
89
86
val task = WdlRewrite .taskGenEmpty(applet.name, scope)
90
87
val inputs = applet.inputs.map{ cVar =>
91
88
WdlRewrite .declaration(cVar.wdlType, cVar.name, None )
@@ -113,7 +110,7 @@ task Add {
113
110
WdlExpression .fromString(sExpr)
114
111
}
115
112
116
- def callUniqueName (call : Call ) = {
113
+ def callUniqueName (call : WdlCall ) = {
117
114
val nm = call.alias match {
118
115
case Some (x) => x
119
116
case None => Utils .taskOfCall(call).name
@@ -136,11 +133,11 @@ task Add {
136
133
// that, in the general case, could be calculated only at runtime.
137
134
// Currently, we support only constants. If a runtime expression is used,
138
135
// we convert it to a moderatly high constant.
139
- def calcInstanceType (taskOpt : Option [Task ]) : IR .InstanceType = {
136
+ def calcInstanceType (taskOpt : Option [WdlTask ]) : IR .InstanceType = {
140
137
def lookup (varName : String ) : WdlValue = {
141
138
throw new DynamicInstanceTypesException ()
142
139
}
143
- def evalAttr (task : Task , attrName : String ) : Option [WdlValue ] = {
140
+ def evalAttr (task : WdlTask , attrName : String ) : Option [WdlValue ] = {
144
141
task.runtimeAttributes.attrs.get(attrName) match {
145
142
case None => None
146
143
case Some (expr) =>
@@ -244,11 +241,6 @@ task Add {
244
241
case a : Ast if a.isMemberAccess =>
245
242
// This is a case of accessing something like A.B.C
246
243
// The RHS is C, and the LHS is A.B
247
- val rhs : Terminal = a.getAttribute(" rhs" ) match {
248
- case rhs: Terminal if rhs.getTerminalStr == " identifier" => rhs
249
- case _ => throw new Exception (cef.rightSideMustBeIdentifer(a))
250
- }
251
-
252
244
// The FQN is "A.B.C"
253
245
val fqn = WdlExpression .toString(a)
254
246
env.get(fqn) match {
@@ -264,8 +256,8 @@ task Add {
264
256
// This is an expression like A.B.C
265
257
varRef => WdlExpression .toString(varRef)
266
258
)
267
- val variables = AstTools .findVariableReferences(a).map{ case t : Terminal =>
268
- WdlExpression .toString(t)
259
+ val variables = AstTools .findVariableReferences(a).map{
260
+ varRef => varRef.terminal.getSourceString
269
261
}
270
262
val allDeps = (memberAccesses ++ variables).map{ fqn =>
271
263
env.get(fqn) match {
@@ -297,7 +289,7 @@ task Add {
297
289
// Print a WDL workflow that evaluates expressions
298
290
def genEvalWorkflowFromDeclarations (name : String ,
299
291
declarations_i : Seq [Declaration ],
300
- outputs : Vector [IR .CVar ]) : Workflow = {
292
+ outputs : Vector [IR .CVar ]) : WdlWorkflow = {
301
293
val declarations =
302
294
if (declarations_i.isEmpty) {
303
295
// Corner case: there are no inputs and no
@@ -359,9 +351,9 @@ task Add {
359
351
val outputVars : Vector [IR .CVar ] = declarations.map{ decl =>
360
352
IR .CVar (decl.unqualifiedName, decl.wdlType, DeclAttrs .empty, decl.ast)
361
353
}.toVector
362
- val code : Workflow = genEvalWorkflowFromDeclarations(appletName,
363
- declarations,
364
- outputVars)
354
+ val code : WdlWorkflow = genEvalWorkflowFromDeclarations(appletName,
355
+ declarations,
356
+ outputVars)
365
357
366
358
// We need minimal compute resources, use the default instance type
367
359
val applet = IR .Applet (appletName,
@@ -432,7 +424,7 @@ workflow w {
432
424
case None => decl
433
425
}
434
426
}.toVector
435
- val code : Workflow = genEvalWorkflowFromDeclarations(appletName,
427
+ val code : WdlWorkflow = genEvalWorkflowFromDeclarations(appletName,
436
428
inputDecls ++ outputDeclarations,
437
429
outputVars)
438
430
@@ -513,7 +505,7 @@ workflow w {
513
505
val (outputs, outputVars) = outputPairs.unzip
514
506
515
507
// Create a workflow with no calls.
516
- val code : Workflow = WdlRewrite .workflowGenEmpty(" w" )
508
+ val code : WdlWorkflow = WdlRewrite .workflowGenEmpty(" w" )
517
509
code.children = inputDecls ++ outputs
518
510
519
511
// Should we reorganize the output folder?
@@ -540,7 +532,7 @@ workflow w {
540
532
}
541
533
542
534
// Compile a WDL task into an applet
543
- def compileTask (task : Task ) : (IR .Applet , Vector [IR .CVar ]) = {
535
+ def compileTask (task : WdlTask ) : (IR .Applet , Vector [IR .CVar ]) = {
544
536
Utils .trace(verbose.on, s " Compiling task ${task.name}" )
545
537
546
538
// The task inputs are those that do not have expressions
@@ -574,19 +566,19 @@ workflow w {
574
566
(applet, outputVars)
575
567
}
576
568
577
- def taskOfCall (call: Call ): Task = {
569
+ def taskOfCall (call: WdlCall ): WdlTask = {
578
570
call match {
579
- case x: TaskCall => x.task
580
- case x: WorkflowCall =>
571
+ case x: WdlTaskCall => x.task
572
+ case x: WdlWorkflowCall =>
581
573
throw new Exception (cef.notCurrentlySupported(call.ast, s " calling a workflow " ))
582
574
}
583
575
}
584
576
585
- def findInputByName (call : Call , cVar : IR .CVar ) : Option [(String ,WdlExpression )] = {
577
+ def findInputByName (call : WdlCall , cVar : IR .CVar ) : Option [(String ,WdlExpression )] = {
586
578
call.inputMappings.find{ case (k,v) => k == cVar.name }
587
579
}
588
580
589
- def compileCall (call : Call ,
581
+ def compileCall (call : WdlCall ,
590
582
taskApplets : Map [String , (IR .Applet , Vector [IR .CVar ])],
591
583
env : CallEnv ) : IR .Stage = {
592
584
// Find the right applet
@@ -643,10 +635,10 @@ workflow w {
643
635
644
636
// Split a block (Scatter, If, ..) into the top declarations,
645
637
// the and the bottom calls.
646
- def blockSplit (children : Vector [Scope ]) : (Vector [Declaration ], Vector [Call ]) = {
638
+ def blockSplit (children : Vector [Scope ]) : (Vector [Declaration ], Vector [WdlCall ]) = {
647
639
val (topDecls, rest) = Utils .splitBlockDeclarations(children.toList)
648
- val calls : Seq [Call ] = rest.map {
649
- case call : Call => call
640
+ val calls : Seq [WdlCall ] = rest.map {
641
+ case call : WdlCall => call
650
642
case decl: Declaration =>
651
643
throw new Exception (cef.notCurrentlySupported(decl.ast,
652
644
" declaration in the middle of a block" ))
@@ -667,7 +659,7 @@ workflow w {
667
659
def blockInputs (preDecls : Vector [Declaration ],
668
660
topBlockExpr : WdlExpression ,
669
661
topDecls : Vector [Declaration ],
670
- calls : Vector [Call ],
662
+ calls : Vector [WdlCall ],
671
663
env : CallEnv ) : (Map [String , LinkedVar ], Vector [IR .CVar ]) = {
672
664
var closure = Map .empty[String , LinkedVar ]
673
665
preDecls.foreach { decl =>
@@ -713,11 +705,11 @@ workflow w {
713
705
// A variable generated by the compiler. It might be used only
714
706
// locally.
715
707
// find all dependent nodes
716
- val dNodes : Set [GraphNode ] = decl.downstream
708
+ val dNodes : Set [WdlGraphNode ] = decl.downstream
717
709
val declParent : Scope = decl.parent.get
718
710
719
711
// figure out if these downstream nodes are in the same scope.
720
- val dnScopes : Set [GraphNode ] = dNodes.filter{ node =>
712
+ val dnScopes : Set [WdlGraphNode ] = dNodes.filter{ node =>
721
713
node.parent.get.fullyQualifiedName != declParent.fullyQualifiedName
722
714
}
723
715
dnScopes.isEmpty
@@ -755,7 +747,7 @@ workflow w {
755
747
.map( decl => IR .CVar (decl.unqualifiedName, decl.wdlType, DeclAttrs .empty, decl.ast) )
756
748
.toVector
757
749
val outputVars : Vector [IR .CVar ] = children.map {
758
- case call: TaskCall =>
750
+ case call: WdlTaskCall =>
759
751
val task = taskOfCall(call)
760
752
task.outputs.map { tso =>
761
753
val varName = callUniqueName(call) ++ " ." ++ tso.unqualifiedName
@@ -777,7 +769,7 @@ workflow w {
777
769
// Check for each task input, if it is unbound. Make a list, and
778
770
// prefix each variable with the call name. This makes it unique
779
771
// as a scatter input.
780
- def unspecifiedInputs (call : Call ,
772
+ def unspecifiedInputs (call : WdlCall ,
781
773
taskApplets : Map [String , (IR .Applet , Vector [IR .CVar ])])
782
774
: Vector [IR .CVar ] = {
783
775
val task = taskOfCall(call)
@@ -823,7 +815,7 @@ workflow w {
823
815
// transform the expressions in a scatter
824
816
def transformChild (scope : Scope ): Scope = {
825
817
scope match {
826
- case tc: TaskCall =>
818
+ case tc: WdlTaskCall =>
827
819
val inputs = tc.inputMappings.map{ case (k,expr) => (k, transform(expr)) }.toMap
828
820
WdlRewrite .taskCall(tc, inputs)
829
821
case d: Declaration =>
@@ -858,12 +850,12 @@ workflow w {
858
850
// calls. However, a scatter calls tasks, that are missing from
859
851
// the WDL file we generate. To ameliorate this, we add stubs
860
852
// for called tasks.
861
- val calls : Vector [Call ] = scope.calls.toVector
862
- val taskStubs : Map [String , Task ] =
863
- calls.foldLeft(Map .empty[String ,Task ]) { case (accu, call) =>
853
+ val calls : Vector [WdlCall ] = scope.calls.toVector
854
+ val taskStubs : Map [String , WdlTask ] =
855
+ calls.foldLeft(Map .empty[String ,WdlTask ]) { case (accu, call) =>
864
856
val name = call match {
865
- case x: TaskCall => x.task.name
866
- case x: WorkflowCall =>
857
+ case x: WdlTaskCall => x.task.name
858
+ case x: WdlWorkflowCall =>
867
859
throw new Exception (cef.notCurrentlySupported(x.ast, " calling workflows" ))
868
860
}
869
861
val (irApplet,_) = taskApplets.get(name) match {
@@ -986,7 +978,7 @@ workflow w {
986
978
}
987
979
988
980
// Compile a workflow, having compiled the independent tasks.
989
- def compileWorkflow (wf : Workflow ,
981
+ def compileWorkflow (wf : WdlWorkflow ,
990
982
taskApplets : Map [String , (IR .Applet , Vector [IR .CVar ])]) : IR .Workflow = {
991
983
Utils .trace(verbose.on, " IR: compiling workflow" )
992
984
@@ -1033,7 +1025,7 @@ workflow w {
1033
1025
val (stage, applet) = compileScatter(wf.unqualifiedName, scatterName, preDecls,
1034
1026
scatter, taskApplets, env)
1035
1027
(stage, Some (applet))
1036
- case BlockScope (call : Call ) =>
1028
+ case BlockScope (call : WdlCall ) =>
1037
1029
val stage = compileCall(call, taskApplets, env)
1038
1030
(stage, None )
1039
1031
case BlockScope (x) =>
@@ -1047,7 +1039,7 @@ workflow w {
1047
1039
case BlockDecl (decls) => cVar.name
1048
1040
case BlockIf (_, _) => cVar.name
1049
1041
case BlockScatter (_, _) => cVar.name
1050
- case BlockScope (call : Call ) => stage.name ++ " ." ++ cVar.name
1042
+ case BlockScope (call : WdlCall ) => stage.name ++ " ." ++ cVar.name
1051
1043
case _ => throw new Exception (" Sanity" )
1052
1044
}
1053
1045
env = env + (fqVarName ->
@@ -1075,13 +1067,13 @@ workflow w {
1075
1067
}
1076
1068
1077
1069
// Load imported tasks
1078
- def loadImportedTasks (ns : WdlNamespace ) : Set [Task ] = {
1070
+ def loadImportedTasks (ns : WdlNamespace ) : Set [WdlTask ] = {
1079
1071
// Make a pass, and figure out what we access
1080
1072
//
1081
- ns.taskCalls.map{ call: TaskCall =>
1073
+ ns.taskCalls.map{ call: WdlTaskCall =>
1082
1074
val taskFqn = call.task.fullyQualifiedName
1083
1075
ns.resolve(taskFqn) match {
1084
- case Some (task: Task ) => task
1076
+ case Some (task: WdlTask ) => task
1085
1077
case x => throw new Exception (s " Resolved call to ${taskFqn} and got ( ${x}) " )
1086
1078
}
1087
1079
}.toSet
@@ -1092,13 +1084,13 @@ workflow w {
1092
1084
Utils .trace(verbose.on, " IR pass" )
1093
1085
1094
1086
// Load all accessed applets, local or imported
1095
- val accessedTasks : Set [Task ] = loadImportedTasks(ns)
1087
+ val accessedTasks : Set [WdlTask ] = loadImportedTasks(ns)
1096
1088
val accessedTaskNames = accessedTasks.map(task => task.name)
1097
1089
Utils .trace(verbose.on, s " Accessed tasks = ${accessedTaskNames}" )
1098
1090
1099
1091
// Make sure all local tasks are included; we want to compile
1100
1092
// them even if they are not accessed.
1101
- val allTasks : Set [Task ] = accessedTasks ++ ns.tasks.toSet
1093
+ val allTasks : Set [WdlTask ] = accessedTasks ++ ns.tasks.toSet
1102
1094
1103
1095
// compile all the tasks into applets
1104
1096
Utils .trace(verbose.on, " compiling tasks into dx:applets" )
0 commit comments