diff --git a/.gitignore b/.gitignore index f73759d797..e4699ebfab 100644 --- a/.gitignore +++ b/.gitignore @@ -118,6 +118,7 @@ buildNumber.properties .flattened-pom.xml ### VisualStudioCode ### +.vscode .vscode/* !.vscode/settings.json !.vscode/tasks.json diff --git a/org.lflang/src/lib/ts/package.json b/org.lflang/src/lib/ts/package.json index f8ea477625..75897da3e7 100644 --- a/org.lflang/src/lib/ts/package.json +++ b/org.lflang/src/lib/ts/package.json @@ -2,20 +2,15 @@ "name": "LinguaFrancaDefault", "version": "0.0.1", "description": "A default Lingua Franca project for the TypeScript target", + "type": "commonjs", "repository": { "type": "git", "url": "https://github.com/icyphy/lingua-franca" }, "license": "BSD-2-Clause", "dependencies": { - "command-line-args": "^5.1.1", - "command-line-usage": "^6.1.0", - "microtime": "^3.0.0", - "ulog": "^2.0.0-beta.7", - "google-protobuf": "^3.7.4", - "uuid": "^8.3.2" - }, - "devDependencies": { + "reactor-ts": "file:./reactor-ts", + "@types/reactor-ts": "file:./reactor-ts", "@babel/cli": "^7.8.4", "@babel/core": "^7.8.7", "@babel/node": "^7.8.7", @@ -25,18 +20,22 @@ "@babel/plugin-transform-modules-commonjs": "^7.8.3", "@babel/preset-env": "^7.8.7", "@babel/preset-typescript": "^7.8.3", + "command-line-usage": "^6.1.0", + "command-line-args": "^5.1.1", + "rimraf": "^3.0.2" + }, + "devDependencies": { "@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/eslint-plugin": "5.33.0", "@typescript-eslint/parser": "^5.8.1", "eslint": "^8.5.0", - "rimraf": "^3.0.2", - "typescript": "^3.8.3", + "typescript": "~4.8.2", "ts-protoc-gen": "^0.12.0" }, "scripts": { "check-types": "tsc", - "build": "rimraf dist && babel src --out-dir dist --extensions .ts,.js" + "build": "npx rimraf dist && npx babel src --out-dir dist --extensions .ts,.js" } } diff --git a/org.lflang/src/lib/ts/reactor-ts b/org.lflang/src/lib/ts/reactor-ts index 05f87e5542..d8356fb0d7 160000 --- a/org.lflang/src/lib/ts/reactor-ts +++ b/org.lflang/src/lib/ts/reactor-ts @@ -1 +1 @@ -Subproject commit 05f87e55422607882a9b0b15f86c8e21c1cfa36d +Subproject commit d8356fb0d78b1f546837bda6611cc19ec8dfca12 diff --git a/org.lflang/src/lib/ts/tsconfig.json b/org.lflang/src/lib/ts/tsconfig.json index af0b62567e..104b89a4c2 100644 --- a/org.lflang/src/lib/ts/tsconfig.json +++ b/org.lflang/src/lib/ts/tsconfig.json @@ -3,6 +3,7 @@ "allowJs": true, "noEmit": true, "target": "esnext", + "types": ["node", "reactor-ts", "ulog", "microtime", "command-line-args", "command-line-usage"], "esModuleInterop": true, "isolatedModules": true, "lib": ["esnext", "dom"], @@ -12,8 +13,9 @@ "strictBindCallApply": true, "strictNullChecks": true, "strictFunctionTypes": true, + "typeRoots": ["./node_modules/@types/", "./node_modules/reactor-ts/src/core/@types/"] }, "include": [ - "src/**/*", + "src/**/*" ] } diff --git a/org.lflang/src/org/lflang/generator/ts/TSFileConfig.kt b/org.lflang/src/org/lflang/generator/ts/TSFileConfig.kt index 7549d2c78b..b2687848df 100644 --- a/org.lflang/src/org/lflang/generator/ts/TSFileConfig.kt +++ b/org.lflang/src/org/lflang/generator/ts/TSFileConfig.kt @@ -61,19 +61,19 @@ class TSFileConfig( /** * Path to TypeScript core source code. */ - fun tsCoreGenPath(): Path = tsSrcGenPath().resolve("core") + fun reactorTsPath(): Path = srcGenPath.resolve("reactor-ts") /** * Path to the generated docker file */ fun tsDockerFilePath(tsFileName: String): Path { - return srcGenPath.resolve(tsFileName + ".Dockerfile") + return srcGenPath.resolve("$tsFileName.Dockerfile") } - + /** * Path to the generated docker compose file */ fun tsDockerComposeFilePath(): Path { return srcGenPath.resolve("docker-compose.yml") } -} \ No newline at end of file +} diff --git a/org.lflang/src/org/lflang/generator/ts/TSGenerator.kt b/org.lflang/src/org/lflang/generator/ts/TSGenerator.kt index 9cb49f4f7b..58eb3cef79 100644 --- a/org.lflang/src/org/lflang/generator/ts/TSGenerator.kt +++ b/org.lflang/src/org/lflang/generator/ts/TSGenerator.kt @@ -82,7 +82,7 @@ class TSGenerator( ) : GeneratorBase(tsFileConfig, errorReporter) { companion object { - /** Path to the Cpp lib directory (relative to class path) */ + /** Path to the TS lib directory (relative to class path) */ const val LIB_PATH = "/lib/ts" /** @@ -91,14 +91,7 @@ class TSGenerator( */ val CONFIG_FILES = arrayOf("package.json", "tsconfig.json", "babel.config.js", ".eslintrc.json") - /** - * Files to be copied from the reactor-ts submodule into the generated - * source directory. - */ - 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") + val RT_CONFIG_FILES = arrayOf("package.json", "package-lock.json", "tsconfig.json", ".babelrc") private val VG = ExpressionGenerator(::timeInTargetLanguage) { param -> "this.${param.name}.get()" } @@ -155,6 +148,7 @@ class TSGenerator( clean(context) copyRuntime() + collectDependencies(resource, context, tsFileConfig.reactorTsPath(), true) copyConfigFiles() val codeMaps = HashMap() @@ -172,7 +166,7 @@ class TSGenerator( context.reportProgress( "Code generation complete. Collecting dependencies...", IntegratedBuilder.GENERATED_PERCENT_PROGRESS ) - if (shouldCollectDependencies(context)) collectDependencies(resource, context) + if (shouldCollectDependencies(context)) collectDependencies(resource, context, tsFileConfig.srcGenPkgPath, false) if (errorsOccurred()) { context.unsuccessfulFinish(); return; @@ -213,10 +207,15 @@ class TSGenerator( * Copy the TypeScript runtime so that it is accessible to the generated code. */ private fun copyRuntime() { - for (runtimeFile in RUNTIME_FILES) { + FileUtil.copyDirectoryFromClassPath( + "$LIB_PATH/reactor-ts/src/core", + tsFileConfig.reactorTsPath().resolve("src").resolve("core"), + true + ) + for (configFile in RT_CONFIG_FILES) { FileUtil.copyFileFromClassPath( - "$LIB_PATH/reactor-ts/src/core/$runtimeFile", - tsFileConfig.tsCoreGenPath().resolve(runtimeFile) + "$LIB_PATH/reactor-ts/$configFile", + tsFileConfig.reactorTsPath().resolve(configFile) ) } } @@ -356,17 +355,14 @@ class TSGenerator( * @param resource The Lingua Franca source file at * which to report any errors * @param context The context of this build. + * @param path The directory for which to get dependencies. + * @param production Whether to get production dependencies only. */ - private fun collectDependencies(resource: Resource, context: LFGeneratorContext) { + private fun collectDependencies(resource: Resource, context: LFGeneratorContext, path: Path, production: Boolean) { Files.createDirectories(fileConfig.srcGenPkgPath) // may throw - val pnpmInstall = commandFactory.createCommand( - "pnpm", - listOf("install"), - fileConfig.srcGenPkgPath, - false // only produce a warning if command is not found - ) + val pnpmInstall = commandFactory.createCommand("pnpm", if (production) listOf("install", "--prod") else listOf("install"), path, false) // Attempt to use pnpm, but fall back on npm if it is not available. if (pnpmInstall != null) { @@ -381,7 +377,7 @@ class TSGenerator( errorReporter.reportWarning( "Falling back on npm. To prevent an accumulation of replicated dependencies, " + "it is highly recommended to install pnpm globally (npm install -g pnpm).") - val npmInstall = commandFactory.createCommand("npm", listOf("install"), fileConfig.srcGenPkgPath) + val npmInstall = commandFactory.createCommand("npm", if (production) listOf("install", "--production") else listOf("install"), path) if (npmInstall == null) { errorReporter.reportError(NO_NPM_MESSAGE) diff --git a/org.lflang/src/org/lflang/generator/ts/TSImportPreambleGenerator.kt b/org.lflang/src/org/lflang/generator/ts/TSImportPreambleGenerator.kt index 2855be06ad..7fa9c26e22 100644 --- a/org.lflang/src/org/lflang/generator/ts/TSImportPreambleGenerator.kt +++ b/org.lflang/src/org/lflang/generator/ts/TSImportPreambleGenerator.kt @@ -51,18 +51,18 @@ class TSImportPreambleGenerator( const val DEFAULT_IMPORTS = """ |import commandLineArgs from 'command-line-args' |import commandLineUsage from 'command-line-usage' - |import {Parameter as __Parameter, Timer as __Timer, Reactor as __Reactor, App as __App} from './core/reactor' - |import {Action as __Action, Startup as __Startup, FederatePortAction as __FederatePortAction} 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' + |import {Parameter as __Parameter, Timer as __Timer, Reactor as __Reactor, App as __App} from 'reactor-ts' + |import {Action as __Action, Startup as __Startup, FederatePortAction as __FederatePortAction} from 'reactor-ts' + |import {Bank as __Bank} from 'reactor-ts' + |import {FederatedApp as __FederatedApp} from 'reactor-ts' + |import {InPort as __InPort, OutPort as __OutPort, Port as __Port} from 'reactor-ts' + |import {InMultiPort as __InMultiPort, OutMultiPort as __OutMultiPort} from 'reactor-ts' + |import {Reaction as __Reaction} from 'reactor-ts' + |import {State as __State} from 'reactor-ts' + |import {TimeUnit, TimeValue, Tag as __Tag, Origin as __Origin} from 'reactor-ts' + |import {Args as __Args, Variable as __Variable, Triggers as __Triggers, Present, Read, Write, ReadWrite, MultiReadWrite, Sched} from 'reactor-ts' + |import {Log} from 'reactor-ts' + |import {ProcessedCommandLineArgs as __ProcessedCommandLineArgs, CommandLineOptionDefs as __CommandLineOptionDefs, CommandLineUsageDefs as __CommandLineUsageDefs, CommandLineOptionSpec as __CommandLineOptionSpec, unitBasedTimeValueCLAType as __unitBasedTimeValueCLAType, booleanCLAType as __booleanCLAType} from 'reactor-ts' |""" } diff --git a/test/README.md b/test/README.md index 6198dc3ebe..284706e6b6 100644 --- a/test/README.md +++ b/test/README.md @@ -9,7 +9,7 @@ The simplest way to run the regression tests is to use a Bash script called `run run-lf-tests C run-lf-tests Cpp run-lf-tests Python -run-lf-tests TS +run-lf-tests TypeScript ``` You can also selectively run just some of the tests. For example, to run the system tests for an individual target language, do this: