Files
compiler-explorer/docs/AddingALanguage.md
Mats Jun Larsen 633eb82d18 Transition to ECMAScript Modules (#4780)
Makes the Compiler Explorer app, and all the tooling ESM compatible.
Things that have been done:

1. The package.json has `type: module` now
2. All relative imports have a .js ending
3. All directory imports are now directory/index.js to comply with ESM
standards
4. Dependency node-graceful is now imported into tree, because the
package is broken under esm
5. Dependency p-queue has been bumped to 7.x with ESM support
6. Dependency profanities has been bumped to 3.x with ESM support
7. Webpack config is now both ESM and CommonJS compatible
8. Non-ESM compatible imports have been rewritten
9. ESLint configuration has been tweaked to not fail on .js imports
10. Mocha is now hacked together and ran with ts-node-esm
11. Webpack is now hacked together and ran with ts-node-esm
12. Webpack config is now ESM compatible, so that it can be used in the
dev server
13. Cypress code still runs commonjs, and has been excluded from the
tsconfig
14. All sinon mock tests have been commented out, because sinon module
mocks do not work with ESModules (because ESModules are immutable)

A lot of tests are now giving warnings/errors to stdout, yet still pass.
Docenizer codegenerator scripts have been updated, but I did not re-run
them, and instead just changed their code.

---------

Co-authored-by: Matt Godbolt <matt@godbolt.org>
2023-02-27 18:06:38 -06:00

4.2 KiB

Adding a new language

If you want to add a new language to the site, you should follow this steps:

  • Add the new language to the exported languages variable in lib/languages.ts:

    • The syntax is as follows:
    'language-key': {
      name: YOUR_LANGUAGE_DISPLAY_NAME,
      monaco: MONACO_MODE_ID,
      extensions: ARRAY_OF_FILE_EXTENSIONS_OF_YOUR_LANGUAGE,
      alias: [], // Leave empty unless needed,
      logoUrl: PATH_TO_LOGO,
      logoUrlDark: PATH_TO_DARK_LOGO, // Optional if not needed
    }
    
    • If the language is supported by Monaco Editor (You can find the list here), you should add it to the list of languages inside the MonacoEditorWebpackPlugin config in webpack.config.esm.ts
    • If not, you should implement your own language mode; see static/modes/asm-mode.js as an example. Don't forget to require your mode file in static/modes/_all.ts, in alphabetical order
    • language-key is how your language will be referred internally by the code. In the rest of this document, replace {language-key} by the corresponding value in the real files.
    • Add a logo file to the views/resources/logos/ folder and add its path to the logoUrl{Dark} key(s) in the language object
  • Add a lib/compilers/{language-key}.js file using the template below:

    import {BaseCompiler} from '../base-compiler';
    
    export class LanguageCompiler extends BaseCompiler {
      static get key() {
        return 'language';
      }
    }
    
    • The value returned by key above corresponds to the compilerType value in etc/config/{language-key}.defaults.properties (Explained below). This is usually {language-key}, but you can use whatever fits best
    • Override the OptionsForFilter method from the base class
    • Comment out the line saying fs.remove(result.dirPath); in base-compiler.js, so the latest CE compile attempt remains on disk for you to review
      • Remember to undo this change before opening a PR!
    • For reference, the basic behaviour of BaseCompiler is:
      • make a random temporary folder
      • save example.extension to the new folder, the full path to this is the inputFilename
      • the outputFilename is determined by the getOutputFilename() method
      • execute the compiler.exe with the arguments from OptionsForFilter() and adding inputFilename
      • be aware that the language class is only instanced once, so storing state is not possible
    • If the compiler has problems with the defaults, you will have to override the runCompiler() method too. When overriding it, here are some ideas
      • set execOptions.customCwd parameter if the working directory needs to be somewhere else
      • set execOptions.env parameter if the compiler requires special environment variables
      • manipulate options, but make sure the user can still add their own arguments in CE
  • Add your LanguageCompiler to lib/compilers/_all.js, in alphabetical order

  • Add a etc/config/{language-key}.local.properties file:

    • The syntax for its basic contents is documented in AddingACompiler.md
    • This file is ignored by Git, so that you can test the config locally
    • You should add 1 compiler for the language you want to test
    • Test the command line options of the language compilers outside CE
  • Add a new file etc/config/{language-key}.defaults.properties. This is where a default configuration will live.

    • Usually, this loads default compilers from their usual paths on a normal installation (Check etc/config/c++.defaults.properties for an example)
  • Of important note, for both files, is to properly define compilerType property in the newly added compilers. This should equal the value returned by your LanguageCompiler.key function

  • Running make dev EXTRA_ARGS="--debug --language {language-key}" to tell CE to only load your new language

  • You can check http://127.0.0.1:10240/api/compilers to be sure your language and compilers are there

  • Make an installer in the infra repository

  • Add your language files ({language-key}.*.properties and lib/compilers/{language-key}.js) to the list in .github/labeler.yml