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

Add bank & multiport support in TypeScript code generator with > 30 multiport tests. #942

Merged
merged 81 commits into from
Mar 11, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
81 commits
Select commit Hold shift + click to select a range
c8639d4
Add a simple multiport test MultiportToPort.lf for TypeScript, to be …
hokeun Feb 4, 2022
aabe437
Add TS as a target that supports multiports, fix error in MultiportTo…
hokeun Feb 6, 2022
51464f6
Merge branch 'master' of github.com:lf-lang/lingua-franca into ts-mul…
hokeun Feb 6, 2022
8c70359
Update reactor-ts version to use _connectMultiplePorts and extended d…
hokeun Feb 6, 2022
913c67e
Add code generation for multiport in TypeScript.
hokeun Feb 6, 2022
4fab0e4
Update multiport test to test writing values to output multiport.
hokeun Feb 6, 2022
77e9f0d
Fix error in non-multiport code generation.
hokeun Feb 6, 2022
fdd48ec
Add MultiportToMultiport.lf test for TypeScript target and add suppor…
hokeun Feb 8, 2022
bf6ac26
Make for loops and forEach in the generated TypeScript code "multi-li…
hokeun Feb 8, 2022
e86bc88
Add multiport check at Variable level and simplify the multiport chec…
hokeun Feb 8, 2022
ca3566a
Add multiport test MultiportIn.lf for TypeScript.
hokeun Feb 8, 2022
6d3381f
Initialize multiport (an array of ports) with the initial size, inste…
hokeun Feb 8, 2022
786476b
Add multiport test MultiportOut.lf for TypeScript.
hokeun Feb 8, 2022
d516944
Merge branch 'master' of github.com:lf-lang/lingua-franca into ts-mul…
hokeun Feb 8, 2022
54dad15
Use spread operator (...) to expand an array of ports instead of hard…
hokeun Feb 8, 2022
23da4c1
Add support for parameterized width for multiports. Add and use Width…
hokeun Feb 8, 2022
94d8a30
Merge branch 'master' of github.com:lf-lang/lingua-franca into ts-mul…
hokeun Feb 8, 2022
8f091bb
Add multiport test MultiportToMultiport2.lf for TypeScript to verify …
hokeun Feb 8, 2022
a43c872
Merge branches 'ts-multiport' and 'master' of github.com:lf-lang/ling…
hokeun Feb 10, 2022
4b97ff2
Add multiport test MultiportToHierarchy.lf for TypeScript to verify m…
hokeun Feb 10, 2022
be26453
Add multiport test MultiportToMultiportArray.lf for TypeScript to ver…
hokeun Feb 10, 2022
fef26a7
Update org.lflang/src/org/lflang/AstExtensions.kt
hokeun Feb 10, 2022
8d5b52c
Use InMultiPort and OutMultiPort instead of arrays of ports, and simp…
hokeun Feb 11, 2022
79acfc8
Merge branch 'master' of github.com:lf-lang/lingua-franca into ts-mul…
hokeun Feb 11, 2022
628a0b7
Fix typescript-eslint errors:
hokeun Feb 11, 2022
3a9d12a
Merge branch 'master' of github.com:lf-lang/lingua-franca into ts-mul…
hokeun Feb 13, 2022
0ead701
Merge branch 'master' of github.com:lf-lang/lingua-franca into ts-mul…
hokeun Feb 13, 2022
774d806
Merge branches 'ts-multiport' and 'master' of github.com:lf-lang/ling…
hokeun Feb 15, 2022
dcbe092
Add BankToMultiport.lf and add code-generation support for Banks and …
hokeun Feb 16, 2022
3af6a47
Add MultiportToBank.lf test and fix minor issues including the non-ty…
hokeun Feb 17, 2022
267fd1d
Merge branch 'master' of github.com:lf-lang/lingua-franca into ts-mul…
hokeun Feb 17, 2022
9246627
Make generateAfterDelaysWithVariableWidth false for TypeScript target…
hokeun Feb 17, 2022
3d991df
Use this.getBankIndex() instead of the bank_index parameter in TypeSc…
hokeun Feb 17, 2022
56b53ed
Add MultiportFromBank.lf test and remove unused code.
hokeun Feb 17, 2022
2aef559
Add 3 multiport tests Broadcast.lf, BankSelfBroadcast.lf, BankMultica…
hokeun Feb 18, 2022
a1d9616
Fix CountTest.lf
hokeun Feb 18, 2022
825e5f3
Merge branch 'master' of github.com:lf-lang/lingua-franca into ts-mul…
hokeun Feb 18, 2022
c1f762e
Add MultiportToMultiport2After.lf and support for generic type mappin…
hokeun Feb 18, 2022
6fab59a
Add BankToBank.lf test.
hokeun Feb 18, 2022
91d8f12
Fix code generation for multiports and banks to make them work with u…
hokeun Feb 22, 2022
2d89ce4
Fix imports and code generation for multiport as a trigger.
hokeun Feb 24, 2022
291736f
Fix code generation for multiports so that it uses allWritable() inte…
hokeun Feb 26, 2022
485905a
Merge branch 'master' of github.com:lf-lang/lingua-franca into ts-mul…
hokeun Feb 26, 2022
5c4cae1
Fix error in generic type mapping.
hokeun Feb 26, 2022
bcde86d
Add FullyConnected.lf test.
hokeun Feb 26, 2022
b3ad432
Fix lsp-test error (Mixed spaces and tabs. [BankToBank.ts])
hokeun Feb 27, 2022
56ae311
Add 3 more TypeScript multiport tests
hokeun Feb 27, 2022
567085e
Add multiport support for referencing hierarchical reactors, for exam…
hokeun Feb 27, 2022
62afeb0
Add 2 multiport tests for contained reactors.
hokeun Feb 27, 2022
f5de3b5
Add uuid to default package.json
hokeun Mar 1, 2022
45c22fc
Merge branch 'master' of github.com:lf-lang/lingua-franca into ts-mul…
hokeun Mar 1, 2022
7662f6f
Adjust to API change for getting the width
lhstrh Mar 1, 2022
5c79f0c
Updated submodule
lhstrh Mar 1, 2022
239ece7
Add 4 more multiport tests for TypeScript target.
hokeun Mar 1, 2022
201c3d9
Fix error in WidthSpec.toTSCode(), add more multiport tests, remove u…
hokeun Mar 1, 2022
6d9dd69
Add ReactionsToNested.lf test and add missing newlines for some TS mu…
hokeun Mar 2, 2022
d5874d1
Merge branch 'master' of github.com:lf-lang/lingua-franca into ts-mul…
hokeun Mar 2, 2022
be0d4d2
Bump reactor-ts version.
hokeun Mar 2, 2022
84c1988
Fix indentation.
hokeun Mar 2, 2022
838ecb0
Merge branch 'master' of github.com:lf-lang/lingua-franca into ts-mul…
hokeun Mar 4, 2022
b5e1377
Match the constructor for Bank and add PipelineAfter.lf test.
hokeun Mar 4, 2022
e996c5e
Add NestedBanks.lf to TypeScript multiport tests.
hokeun Mar 4, 2022
65fbd56
Update reactor-ts submodule
lhstrh Mar 7, 2022
7b6f98f
Merge branch 'master' of github.com:lf-lang/lingua-franca into ts-mul…
hokeun Mar 8, 2022
0e0aa71
Add MultiportToMultiportParameter.lf to test.
hokeun Mar 8, 2022
95472cf
Remove logging that is not relevant typescript target.
hokeun Mar 8, 2022
e274bce
Simplify multi connection generation using .port() API.
hokeun Mar 9, 2022
6afeebd
Add newlines at the end of TS multiport tests.
hokeun Mar 9, 2022
2c652a8
Update the reactor-ts version to fix the error with type mismatch bet…
hokeun Mar 9, 2022
4e4686b
Add support for port of bank used as a trigger (e.g., b.out used as a…
hokeun Mar 9, 2022
997be6d
Add test/TypeScript/src/multiport/BankMultiportToReaction.lf.
hokeun Mar 9, 2022
12a82fa
Refactor reaction signature generation code for port effects.
hokeun Mar 9, 2022
9d91b7a
Add support for effect ports from banks, and add BankReactionsInConta…
hokeun Mar 9, 2022
8a27369
Update reactor-ts version.
hokeun Mar 9, 2022
ba5745b
Add two more TypeScript multiport tests.
hokeun Mar 9, 2022
9bfd8c1
Add a new line at the end of test.
hokeun Mar 9, 2022
69136a0
Resolve conflict
lhstrh Mar 11, 2022
6613c55
Merged in master; resolved confict.
lhstrh Mar 11, 2022
b271246
Fix compile error
lhstrh Mar 11, 2022
20016e4
Update submodule
lhstrh Mar 11, 2022
ce506ff
Remove threads target properties from templates. How come this was no…
lhstrh Mar 11, 2022
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
Expand Up @@ -3,7 +3,6 @@
* This has no audio output, but just tests the ncurses interface.
*/
target C {
threads: 2,
cmake-include: [
"include/ncurses-cmake-extension.txt", // Adds support for ncurses
"/lib/c/reactor-c/util/sensor_simulator.cmake"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,13 @@
* transport the input to the output. Four of them are
* instantiated. Note that without parallel execution, there is
* no way this program can keep up with real time since in every
* 200 msec cycle it has 800 msec of work to do. Given 4 threads,
* 200 msec cycle it has 800 msec of work to do. Given 4 workers,
* however, this program can complete 800 msec of work in about
* 225 msec.
*/
target C {
timeout: 2 sec,
threads: 1, // Change to 4 to see speed up.
workers: 1, // Change to 4 to see speed up.
};
reactor Source {
timer t(0, 200 msec);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,19 @@
* a chain of reactors that can all execute in parallel
* at each logical time step.
*
* The threads argument specifies the number of worker
* threads, which enables the reactors in the chain to
* The workers argument specifies the number of worker
* workers, which enables the reactors in the chain to
* execute on multiple cores simultaneously.
*
* This uses the TakeTime reactor to perform computation.
* If you reduce the number of worker threads to 1, the
* If you reduce the number of worker workers to 1, the
* execution time will be approximately four times as long.
*
* @author Edward A. Lee
* @author Marten Lohstroh
*/
target C {
threads: 4,
workers: 4,
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
* @author Marten Lohstroh
*/
target C {
threads: 1,
keepalive: true
};
/**
Expand Down
4 changes: 3 additions & 1 deletion org.lflang/src/lib/ts/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@
"command-line-usage": "^6.1.0",
"microtime": "^3.0.0",
"ulog": "^2.0.0-beta.7",
"google-protobuf": "^3.7.4"
"google-protobuf": "^3.7.4",
"uuid": "^8.3.2"
},
"devDependencies": {
"@babel/cli": "^7.8.4",
Expand All @@ -26,6 +27,7 @@
"@babel/preset-typescript": "^7.8.3",
"@types/google-protobuf": "^3.7.4",
"@types/node": "^13.9.2",
"@types/uuid": "^8.3.4",
"@typescript-eslint/eslint-plugin": "^5.8.1",
"@typescript-eslint/parser": "^5.8.1",
"eslint": "^8.5.0",
Expand Down
2 changes: 1 addition & 1 deletion org.lflang/src/lib/ts/reactor-ts
Submodule reactor-ts updated 58 files
+6 −13 .github/workflows/api-docs.yml
+47 −0 .github/workflows/ci.yml
+2 −2 .gitignore
+3 −2 README.md
+3 −6 __tests__/ActionTrigger.test.ts
+1 −1 __tests__/Adder.test.ts
+3 −5 __tests__/Clock.test.ts
+4 −5 __tests__/HierarchicalSingleEvent.test.ts
+1 −5 __tests__/Logger.test.ts
+1 −2 __tests__/OutputEvent.test.ts
+2 −4 __tests__/OutputGet.test.ts
+1 −3 __tests__/SingleEvent.test.ts
+70 −3 __tests__/alarm.ts
+56 −0 __tests__/bank.ts
+99 −0 __tests__/connection.test.ts
+0 −91 __tests__/defunct/Deadline.ts
+25 −20 __tests__/dependencies.ts
+45 −80 __tests__/hierarchy.ts
+92 −0 __tests__/multiport.test.ts
+4 −6 __tests__/mutations.test.ts
+4 −5 __tests__/reactors.errors.test.ts
+1 −4 __tests__/reactors.test.ts
+27 −20 __tests__/simple.ts
+58 −0 __tests__/time.test.ts
+0 −65 __tests__/types/canConnect.ts
+0 −2 __tests__/types/index.d.ts
+0 −18 __tests__/types/tsconfig.json
+0 −7 __tests__/types/tslint.json
+1 −0 lingua-franca-ref.txt
+935 −2,239 package-lock.json
+6 −3 package.json
+462 −0 src/benchmark/FacilityLocation.ts
+2 −4 src/benchmark/PingPong.ts
+7 −6 src/benchmark/Sieve.ts
+142 −0 src/core/action.ts
+99 −0 src/core/bank.ts
+1 −2 src/core/cli.ts
+75 −53 src/core/component.ts
+61 −0 src/core/event.ts
+74 −51 src/core/federation.ts
+16 −0 src/core/internal.ts
+257 −0 src/core/multiport.ts
+195 −0 src/core/port.ts
+8 −4 src/core/reaction.ts
+282 −696 src/core/reactor.ts
+33 −0 src/core/state.ts
+29 −0 src/core/strings.ts
+26 −0 src/core/time.ts
+127 −0 src/core/trigger.ts
+109 −0 src/core/types.ts
+3 −0 src/core/util.ts
+0 −99 src/example/generated/DistributedLogical/Distributed_dsp.ts
+0 −114 src/example/generated/DistributedLogical/Distributed_msg.ts
+0 −97 src/example/generated/DistributedPhysical/Distributed_dsp.ts
+0 −112 src/example/generated/DistributedPhysical/Distributed_msg.ts
+0 −27 src/example/generated/README.md
+2 −1 src/share/Logger.ts
+1 −1 src/share/SingleEvent.ts
5 changes: 5 additions & 0 deletions org.lflang/src/org/lflang/AstExtensions.kt
Original file line number Diff line number Diff line change
Expand Up @@ -373,6 +373,11 @@ val Action.isPhysical get() = this.origin == ActionOrigin.PHYSICAL
*/
val Port.isMultiport get() = ASTUtils.isMultiport(this)

/**
* Return true if the receiving Variable is a port and a multiport.
*/
val Variable.isMultiport get() = (this is Port) && this.isMultiport

/** Get the reactor that is instantiated in the receiving instantiation. */
val Instantiation.reactor get() = this.reactorClass.toDefinition()

Expand Down
2 changes: 2 additions & 0 deletions org.lflang/src/org/lflang/Target.java
Original file line number Diff line number Diff line change
Expand Up @@ -473,6 +473,7 @@ public boolean supportsMultiports() {
case CPP:
case Python:
case Rust:
case TS:
return true;
}
return false;
Expand All @@ -491,6 +492,7 @@ public boolean supportsParameterizedWidths() {
case CPP:
case Python:
case Rust:
case TS:
return true;
}
return false;
Expand Down
57 changes: 45 additions & 12 deletions org.lflang/src/org/lflang/generator/ts/TSConnectionGenerator.kt
Original file line number Diff line number Diff line change
@@ -1,7 +1,15 @@
package org.lflang.generator.ts

import org.lflang.ErrorReporter
import org.lflang.hasMultipleConnections
import org.lflang.isBank
import org.lflang.isInput
import org.lflang.isMultiport
import org.lflang.lf.Connection
import org.lflang.lf.Port
import org.lflang.lf.Reactor
import org.lflang.lf.VarRef
import org.lflang.toText
import java.util.*

/**
Expand All @@ -14,30 +22,55 @@ class TSConnectionGenerator (
) {
// There is no generateClassProperties() for connections

private fun getPortName(port: VarRef): String {
var portName = ""
if (port.container != null) {
if (port.container.isBank) {
portName += "...this.${port.container.name}.port(it => it.${port.variable.name})"
return portName
}
portName += port.container.name + "."
}
portName += port.variable.name
return "this.$portName"
}

hokeun marked this conversation as resolved.
Show resolved Hide resolved
/**
* Return names of the ports on multiple connections.
*/
private fun getPortNames(ports: List<VarRef>): List<String> {
var portNames = LinkedList<String>()
for (varRef in ports) {
portNames.add(getPortName(varRef))
}
return portNames
}

fun generateInstantiations(): String {
val connectionInstantiations = LinkedList<String>()
for (connection in connections) {
var leftPortName = ""
// FIXME: Add support for multiports.
if (connection.leftPorts.size > 1) {
errorReporter.reportError(connection, "Multiports are not yet supported in the TypeScript target.")
if (connection.hasMultipleConnections) {
var leftPortNames = getPortNames(connection.leftPorts)
var rightPortNames = getPortNames(connection.rightPorts)
val leftPortName = leftPortNames.joinToString(prefix = "[", separator = ", ", postfix = "]")
val rightPortName = rightPortNames.joinToString(prefix = "[", separator = ", ", postfix = "]")
connectionInstantiations.add("this._connectMulti($leftPortName, $rightPortName, ${connection.isIterated});")
} else {
var leftPortName = ""

if (connection.leftPorts[0].container != null) {
leftPortName += connection.leftPorts[0].container.name + "."
}
leftPortName += connection.leftPorts[0].variable.name
}
var rightPortName = ""
if (connection.leftPorts.size > 1) {
errorReporter.reportError(connection, "Multiports are not yet supported in the TypeScript target.")
} else {
var rightPortName = ""

if (connection.rightPorts[0].container != null) {
rightPortName += connection.rightPorts[0].container.name + "."
}
rightPortName += connection.rightPorts[0].variable.name
}
if (leftPortName != "" && rightPortName != "") {
connectionInstantiations.add("this._connect(this.$leftPortName, this.$rightPortName);")
if (leftPortName != "" && rightPortName != "") {
connectionInstantiations.add("this._connect(this.$leftPortName, this.$rightPortName);")
}
}
}
return connectionInstantiations.joinToString("\n")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,6 @@ class TSConstructorGenerator (
private fun getInitializerList(param: Parameter): List<String> =
tsGenerator.getInitializerListW(param)

private fun Parameter.getTargetType(): String = tsGenerator.getTargetTypeW(this)

// Initializer functions
private fun getTargetInitializerHelper(param: Parameter,
list: List<String>): String {
Expand Down
50 changes: 50 additions & 0 deletions org.lflang/src/org/lflang/generator/ts/TSExtensions.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package org.lflang.generator.ts

import org.lflang.isBank
import org.lflang.isMultiport
import org.lflang.lf.Parameter
import org.lflang.lf.Port
import org.lflang.lf.Type
import org.lflang.lf.WidthSpec
import org.lflang.toText

/**
* The following definition provide extension that are useful for TypeScript target.
*
* @author {Hokeun Kim <[email protected]>}
*/
fun WidthSpec.toTSCode(): String = terms.joinToString(" + ") {
when {
it.parameter != null -> "${it.parameter.name}"
it.port != null -> with(it.port) {
if (container?.isBank == true) {
if ((variable as Port).isMultiport) "this.${container.name}.all().length * this.${container.name}.all()[0].${variable.name}.width()"
else "this.${container.name}.all().length"
} else {
if ((variable as Port).isMultiport) "this.${container.name}.${variable.name}.width()"
else "1"
}
}
it.code != null -> it.code.toText()
else -> it.width.toString()
}
}

private fun Type.getTargetType(): String = TSTypes.getTargetType(this)

/**
* Return a TS type for the specified port.
* If the type has not been specified, return
* "Present" which is the base type for ports.
* @param port The port
* @return The TS type.
*/
fun getPortType(port: Port): String {
if (port.type != null) {
return port.type.getTargetType()
} else {
return "Present"
}
}

fun Parameter.getTargetType(): String = TSTypes.getTargetType(this)
10 changes: 6 additions & 4 deletions org.lflang/src/org/lflang/generator/ts/TSGenerator.kt
Original file line number Diff line number Diff line change
Expand Up @@ -95,10 +95,10 @@ class TSGenerator(
* Files to be copied from the reactor-ts submodule into the generated
* source directory.
*/
val RUNTIME_FILES = arrayOf("cli.ts", "command-line-args.d.ts",
"command-line-usage.d.ts", "component.ts", "federation.ts", "reaction.ts",
"reactor.ts", "microtime.d.ts", "nanotimer.d.ts", "time.ts", "ulog.d.ts",
"util.ts")
val RUNTIME_FILES = arrayOf("action.ts", "bank.ts", "cli.ts", "command-line-args.d.ts",
"command-line-usage.d.ts", "component.ts", "event.ts", "federation.ts", "internal.ts",
"reaction.ts", "reactor.ts", "microtime.d.ts", "multiport.ts", "nanotimer.d.ts", "port.ts",
"state.ts", "strings.ts", "time.ts", "trigger.ts", "types.ts", "ulog.d.ts", "util.ts")

private val VG = ValueGenerator(::timeInTargetLanguage) { param -> "this.${param.name}.get()" }

Expand Down Expand Up @@ -653,4 +653,6 @@ class TSGenerator(
override fun getTarget(): Target {
return Target.TS
}

override fun generateAfterDelaysWithVariableWidth() = false
}
Original file line number Diff line number Diff line change
Expand Up @@ -51,10 +51,16 @@ class TSImportPreambleGenerator(
const val DEFAULT_IMPORTS = """
|import commandLineArgs from 'command-line-args'
|import commandLineUsage from 'command-line-usage'
|import {Args as __Args, Present, Parameter as __Parameter, State as __State, Variable as __Variable, Read, Triggers as __Triggers, ReadWrite, Write, Action as __Action, Startup as __Startup, Sched, Timer as __Timer, Reactor as __Reactor, Port as __Port, OutPort as __OutPort, InPort as __InPort, App as __App} from './core/reactor'
|import {Reaction as __Reaction} from './core/reaction'
|import {Parameter as __Parameter, Timer as __Timer, Reactor as __Reactor, App as __App} from './core/reactor'
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should eventually change this and import everything from 'reactor-ts' once we've published it as a package. Let's do this soon.

|import {Action as __Action, Startup as __Startup} from './core/action'
|import {Bank as __Bank} from './core/bank'
|import {FederatedApp as __FederatedApp} from './core/federation'
|import {InPort as __InPort, OutPort as __OutPort, Port as __Port} from './core/port'
|import {InMultiPort as __InMultiPort, OutMultiPort as __OutMultiPort} from './core/multiport'
|import {Reaction as __Reaction} from './core/reaction'
|import {State as __State} from './core/state'
|import {TimeUnit, TimeValue, Tag as __Tag, Origin as __Origin} from './core/time'
|import {Args as __Args, Variable as __Variable, Triggers as __Triggers, Present, Read, Write, ReadWrite, MultiReadWrite, Sched} from './core/types'
|import {Log} from './core/util'
|import {ProcessedCommandLineArgs as __ProcessedCommandLineArgs, CommandLineOptionDefs as __CommandLineOptionDefs, CommandLineUsageDefs as __CommandLineUsageDefs, CommandLineOptionSpec as __CommandLineOptionSpec, unitBasedTimeValueCLAType as __unitBasedTimeValueCLAType, booleanCLAType as __booleanCLAType} from './core/cli'
|"""
Expand Down
45 changes: 35 additions & 10 deletions org.lflang/src/org/lflang/generator/ts/TSInstanceGenerator.kt
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
package org.lflang.generator.ts

import org.lflang.ErrorReporter
import org.lflang.federated.FederateInstance
import org.lflang.isBank
import org.lflang.lf.Instantiation
import org.lflang.lf.Parameter
import org.lflang.lf.Reactor
import org.lflang.lf.TypeParm
import org.lflang.reactor
import org.lflang.toDefinition
import org.lflang.toText
import java.util.*
Expand All @@ -14,6 +18,7 @@ import java.util.*
class TSInstanceGenerator (
// TODO(hokeun): Remove dependency on TSGenerator.
private val tsGenerator: TSGenerator,
private val errorReporter: ErrorReporter,
private val tsReactorGenerator: TSReactorGenerator,
reactor: Reactor,
federate: FederateInstance
Expand All @@ -39,12 +44,26 @@ class TSInstanceGenerator (
return tsReactorGenerator.getTargetInitializerHelper(param, getInitializerList(param, i))
}

private fun getTypeParams(typeParms: List<TypeParm>): String =
if (typeParms.isEmpty()) {""} else {
typeParms.joinToString(", ", "<", ">") { it.toText() }}

private fun getReactorParameterList(parameters: List<Parameter>): String =
if (parameters.isEmpty()) { "[__Reactor]" } else {
parameters.joinToString(", ", "[__Reactor, ", "]") { it.getTargetType() }}


fun generateClassProperties(): String {
val childReactorClassProperties = LinkedList<String>()
for (childReactor in childReactors) {
val childReactorParams = if (childReactor.typeParms.isEmpty()) {""} else {
childReactor.typeParms.joinToString(", ", "<", ">") { it.toText() }}
childReactorClassProperties.add("${childReactor.name}: ${childReactor.reactorClass.name}$childReactorParams")
if (childReactor.isBank) {
childReactorClassProperties.add("${childReactor.name}: " +
"__Bank<${childReactor.reactorClass.name}${getTypeParams(childReactor.typeParms)}, " +
"${getReactorParameterList(childReactor.reactor.parameters)}>")
} else {
childReactorClassProperties.add("${childReactor.name}: " +
"${childReactor.reactorClass.name}${getTypeParams(childReactor.typeParms)}")
}
}
return childReactorClassProperties.joinToString("\n")
}
Expand All @@ -55,16 +74,22 @@ class TSInstanceGenerator (
val childReactorArguments = StringJoiner(", ");
childReactorArguments.add("this")

// Iterate through parameters in the order they appear in the
// reactor class, find the matching parameter assignments in
// the reactor instance, and write the corresponding parameter
// value as an argument for the TypeScript constructor
for (parameter in childReactor.reactorClass.toDefinition().parameters) {
childReactorArguments.add(getTargetInitializer(parameter, childReactor))
}

childReactorInstantiations.add(
"this.${childReactor.name} = new ${childReactor.reactorClass.name}($childReactorArguments)")
if (childReactor.isBank) {
childReactorInstantiations.add(
"this.${childReactor.name} = " +
"new __Bank<${childReactor.reactorClass.name}${getTypeParams(childReactor.typeParms)}, " +
"${getReactorParameterList(childReactor.reactor.parameters)}>" +
"(this, ${childReactor.widthSpec.toTSCode()}, " +
"${childReactor.reactorClass.name}, " +
"$childReactorArguments)")
} else {
childReactorInstantiations.add(
"this.${childReactor.name} = " +
"new ${childReactor.reactorClass.name}($childReactorArguments)")
}
}
return childReactorInstantiations.joinToString("\n")
}
Expand Down
Loading