N4JS Language & IDE

N4JS Language and IDE Features

The following table gives an overview of features implemented by N4JS.

Remarks

  • The parser fully supports ECMAScript 2015 syntax including unicode escape sequences, regular expressions and automatic semicolon insertion. Not all constructs are fully supported by the type-checker yet.

  • The transpiler translates N4JS to V8-compatible JavaScript. ES2015 constructs not supported by latest V8 are rejected by N4JS.

  • Except project (as an access modifier, will be removed in future versions as it is the default), N4JS does not introduce any new keywords to ECMAScript 2015/ES.next. If additional functionality requires explicit declarations, this is done via annotations similar to Java (using @). There are no user-defined annotations supported at the moment (this is why we do not list annotations as a feature).

Feature Table

Statements and expressions

Feature

Similar to

Description

ECMAScript 5

ES5

ES5 expressions, statements and declarations are fully supported (except scoping in with-statement) including type constraints and inference.

Import, Export

ES2015

import statement fully supported, exporting declarations is supported, re-export not fully supported yet, no relative imports, no anonymous default export.

Scoping and access restrictions

for..of loops

ES2015

Fully supported including destructuring.

Function scoping

ES5

ES5-like function scoping with var

Block scoping

ES2015

ES2015-like block scoping with let and const

Constants

ES2015

const variables (requiring initializers at declaration) with block scoping using keyword const

Final fields

Java

final fields (requiring initialization in constructor) with annotation @Final

Access modifiers

Java

Access modifiers almost similar to Java: public, protected, private. Instead of package, project is introduced limiting access to the current project or component. For larger projects with components from multiple vendors, an additional modifier @Internal is introduced to restrict access to vendor-types only.

String templates

ES2015

ES2015-like string templates with validation (of expressions inside the template).

Functions

Function objects

ES

Function (and method) expressions and declarations are modeled as function objects (with function type)

Function subtyping

Java+ES

Override compatibility (similar to Java) with notion of ECMAScript semantics (superfluous or variadic parameters)

Arrow expression

ES2015

Arrow functions with this binding according to ES2015

Rest parameters

ES2015

Fully supported, parameters are treated as arrays inside function

Optional parameters

Parameters can be marked optional. This is going to be replaced with ES2015 default parameters.

Super calls

ES2015

Inside methods (of classes), super can be used to call overridden method (or constructor)

Generators

ES2015

Syntax supported but not supported by language (type checker) yet.

Declared types

Classes

ES2015/Java

Class declarations as in ES2015 (or Java) with single inheritance but implementation of multiple interfaces as in Java)

Interfaces

Java

Interface declarations with default methods (as in Java 8) and data fields (treated as default implementation, can be implemented with field accessors). instanceof operator can be used with interfaces as well.

Enumeration

˜ TS

Simple enumerations with literals and basic reflection

String-based enums

string based enumerations, literals are of type string

Methods

ES2015

Methods as in ES2015, including constructor and static methods; overridden or implemented members are to be annotated with @Override as in Java

Field accessors

ES2015

Getters and setters (in object literals and classes, instance and static); at the moment pairs are automatically recognized, will be changed to ES2015 semantics

Data fields

Java

Instance and static fields including initializers as in Java

Class modifiers

Java

As in Java, classes can be declared abstract or final (using @Final annotation).

Types

Type annotation

ES4

Type annotations using colon syntax similar to ECMAScript 4 proposal or TS, some special types use different syntax (will probably be adjusted to be compatible with TS)

any

TS

Top type (super type of every other type), used as default type in N4JS files if no more specific type is declared or can be inferred. No property access is possible, since any has no properties. This is probably the most important difference to TypeScript: In TypeScript anything can be called on any, in N4JS nothing! However, this can be changed with a dynamic modifier, see below.

Primitives

ES

primitive types as in ES5 (number, string, boolean), special types null and undefined (with special variant void to be used for return type)

int

primitive type int, at the moment used synonymously to number, will be stricter checked and handled in future releases

Symbols

ES2015

minimal support for symbols, basically only predefined symbols, more support may be added

Nominal types

Java

By default, all subtyping is done nominally as in Java, i.e. subtype relations are to be explicitly declared with extends and implements

Structural types

˜ TS

Modifiers at declarations or references enable structural subtyping. Access modifiers are taken in to account, i.e. only public members become part of a structural type.

Field structural type

Similar to structural typing, but only fields (data/accessors) are taken into account. Different variants (all fields, read-only fields/getter, write-only fields/setter, initializer variant for special constructor initializer) supported.

Static types

Java

By default, only declared properties of a type can be accessed. This is true independent from the syntax (property access with dot-syntax (a.x) or index access (a["x"]). To model the map-behavior of Object, arbitrary index access on variables of type Object is allowed.

Dynamic types

Type modifier + enables arbitrary property access. Actually any+ is similar to TypeScript’s any semantics. This is known to be unsafe, so it is not the default behavior (in particular not for any) but only to be used as an "escape hatch".

Arrays

ES

Arrays are modeled as a generic type (extending Object)

Object literals

ES

Object literals are modeled as structural types (\~Object with { properties })

Type cast

˜ TS

Expressions can be explicitly casted to a type via as

Generics

Generic types

Java

Generic class and interface declarations, parameterized type references (raw type usage not allowed)

Generic functions and methods

Java

Generic functions (and methods)

Type variables, wildcards

Java

Type variables (in declarations) and wildcards (in references) with upper and lower bounds</tr>

Type variable inference

Java

Type variables are inferred if not explicitly bound by type arguments in the reference, this is particularly important for generic function/method calls. The type inference algorithm matches the Java 8 specification.

Type Constructors and Special Types

Union type

˜ TS

An union type defines that a variable (of that type) is subtype of (at least) one type defined in the union. Without further type checks, only members available in all types of the union are available. In case of methods, formal parameter types are merged by means of intersection types (and return types by means of union types)

Intersection type

TS

An intersection type defines that a variable (of that type) is subtype of all types defined in the intersection. Thus, members defined in any type of the union are available. Property access to intersection types is not fully supported yet.

Constructor type

˜ TS

Type of a (non-abstract) class declaration or expression itself. Special subtyping rules are implemented, i.e. constructor signature is taking into account.

type type

Type of a class or interface declaration, without any constructor. That is, variables of this type cannot be used in new-expressions. However, this type is useful in combination with static polymorphism.</tr>

this type

˜ TS

Type of the this-literal, can be used in combination with structural typing. Via annotation @This this type can be explicitly defined for functions.

Dynamic polyfills

In order to model the commonly used pattern of polyfills and to add new properties to built-in types (as in ES2015), dynamic polyfills can be defined (in definition modules only). They look like partial classes. The modules defining these polyfills may define (plain JS) modules which are to be executed at initialization time in order to apply the polyfills at runtime.

Static polyfills

In larger projects, often classes are automatically generated. In order to enrich these classes without changing the generator, static polyfills can be defined. The transpiler merges these static polyfills into the original modules.

Asynchronous Programming

Promise

ES2015

Object type Promise as defined in ECMAScript 2015 defined as ES2015 API type

Async/await

ES.next

async and await keywords for implicit promises, syntax and semantics closely follow ES proposal; transpiled to generator functions; validation checks correct usage of async await, async functions will implicitly return Promises. async can be used with function or method declarations, function and arrow expressions

Promisifiable

Via annotations @Promisifiable ES5-conform functions following code conventions for asynchronous callback parameters (last parameter is a callback function etc.) can be used as if they were defined with async keyword, i.e. they can be used with await keyword (or a promise can be retrieved via annotation @Promisify)

Components and Modules

Components

N4JS and the N4JS IDE use the notion of components (or projects). An N4JS component is described with a manifest, in which the component and its dependencies are defined. N4JS introduces different component types: Runtime libraries and runtime environments define capabilities of specific JavaScript engines and execution environments (such as node.js vs. browser); test components have extended access to the tested components

Modules

ES2015

N4JS defines modules similar to ES2015, these modules are transpiled to V8-compatible JavaScript

Type definition modules

TS

In order to provide type annotations for existing projects, definition files (n4jsd) are used.

Module Loader

ES5/ES2015

Unified output with support for System.js and Common.js (Node.js implementation) module loaders. Since System.js enables better handling of dependency cycles, this is the default loader used by the IDE

Dependency Injection

Java

Dependency injection is supported using annotations similar to JSR-330 (probably better known from Guice) and more to reduce client side glue code. Fields (and parameters) can be injected via @Inject, injectors can be easily set up via @GenerateInjector and configured with binders (and @Bind annotation). The built-in framework supports nesting of injectors, different injection points (field, constructor, method), providers and different scopes (default, singleton, injection-chain-singleton).

API

ES5 object types

ES

All ECMAScript 5 object types are available in N4JS, type annotations are built-in

ES2015 object types

ES2015

ECMAScript 2015 object types are defined by means of runtime libraries and a runtime environment. N4JS does not provide any implementation of these object types. Also, not all details are defined yet. This will be updated in future releases, depending also on V8 capabilities. However, the most important object types such as collections are defined already.

Reflection

Besides ECMAScript reflection mechanisms, N4JS provides additional reflection at runtime via a built-in class N4Class. This class provides basic information at the moment, this will be improved in future releases

Testing

JUnit-like annotations

Java

Tests can be annotated similar to JUnit, i.e. tests methods with @Test, setup code with @Before/@BeforeAll etc.

Built-in Test Framework

An xUnit-like test framework "mangelhaft" using test annotations is provided with the IDE

Extended Access

Test classes (in special test components) have extended access to tested projects, e.g., can access non-public members

Test Execution

Tests can be started from the IDE using node.js. It is possible to run single test modules, single methods, or whole packages/projets.

node.js Support

Dynamic Import

In order to use projects without type annotations, the dynamic module import can be used to make the module dynamic (so that arbitrary properties can be accessed)

Automatic download of Type Definitions

If available, type definitions are automatically downloaded when an NPM module is installed via the IDE. New type definitions will be added in the future.

Execution

Modules can be run from the IDE using node.js, either using module loader System.js (default) or Common.js

npm Export

Components an be exported to the file system, package.json is automatically created and content is organized according to NPM convention — ready to be published with NPM (which is not done automatically in order to avoid rash publications)

N4JS IDE Features

Syntax highlighting

Syntax highlighting with special highlighting of type annotations, can be used for editing n4js, n4jsd or plain js files

Immediate validation

Code is validated as you type

Incremental builder

Code is transpiled as you save, only effected modules will be re-compiled

Content assist

Basic content assist (propose properties of the receiver, keywords) is working; will be improved in future releases

Quickfixes

Quick fixes to solve common issues, e.g. adding missing annotations or modifiers; more quickfixes will be added in future releases

Wizards

Wizards for creating new projects, classes or interfaces. More wizards will be added in future releases

Organize imports

Automatically add missing imports and remove unused imports. A lso content assist and quickfixes will add imports - you never have to type import statements.

Project and outline view

Project view showing all components in workspace, (quick) outline view to easily navigate to declared elements.

Jump to declaration

Navigate from reference to bound declaration

Find all references

Find all references bound to a declaration

Error reporting

We embrace bug reports! In order to enable easier writing of bug reports, language tests can be written inside the IDE. This feature will be improved in the future.

Eclipse-powered

Since the IDE is based on Eclipse, additional features such as git support are integrated or can easily be installed

N4JS Headless Compiler

n4jsc

The headless compiler is workspace aware, i.e. it can compile all projects with a single command. This makes it very easy to set up CI jobs. At the moment, the headless compiler is made available as a jar-file. Additional support simplifying installation and usage will be added in future releases

Legend

FeatureTable

green

available, although there might be bugs in the alpha-release.

yellow

mostly available, some aspects or parts of the feature are not implemented yet or will be improved in the future.

orange

feature available but syntax or semantics will be changed in future releases

red

planned for future releases but not implemented yet.

References

References

ES

ECMAScript Language Specification / ISO/IEC. Geneva, Switzerland, Juni 2011 (ECMA-262, 5.1 Edition)

ES2015

ECMAScript 2015 Language Specification / ISO/IEC (ECMA-262, 6th Edition). โ€“ International Standard.

ES4

Proposed ECMAScript 4th Edition โ€“ Language Overview / ECMA. โ€“ Proposal, PDF.

ES.next

ECMAScript proposals (ECMAScript 2017 or later or never)

TS

Hejlsberg, Anders ; Lucco, Steve: TypeScript Language Specification. 1.8. Microsoft, Januar 2016. ˜ TS means almost similar functionality, !TS refers to similar concepts but with major differences.

Java

Gosling, James et al: The Java Language Specification. Java SE 8 Edition. JSR-337 Java SE 8 Release Contents.