Code Monkey home page Code Monkey logo

n4js's Introduction

N4JS

The Eclipse N4JS language and IDE enable high-quality JavaScript development for large Node.js projects. N4JS enriches ECMAScript with a static type system and provides extensive support for static validation hosted within a feature-rich IDE.

N4JS is based on ECMAScript Version 5 and ECMAScript 2015 is supported to a great extent. It adds a sound static type system inspired by Java 8, extended by concepts such as structural typing or union types. The language provides built-in support for state-of-the-art programming paradigms such as dependency injection and robust test support. The Eclipse based IDE for typed JavaScript is custom-built for exactly these concepts. Code is validated as you type in addition to tools such as content-assist and quick-fixes to ensure your code is written safely and intuitively.

Releases

The Eclipse N4JS project is in the Incubation Phase and there is no official release available yet (for unofficial releases see the download page. This doesn’t mean that N4JS is unstable; we have an extensive test suite (>90.000 tests including the ECMAScript test suites) to ensure a stable nightly build. N4JS has been in use in several large non-public projects for years. There still may be bugs (as there are always bugs) and features which are currently under development. We encourage feedback from all users! For questions about getting started with the N4JS Language and IDE for developing your own projects, see the the Eclipse N4JS forum.

Contribute

Eclipse developers who want to develop N4JS itself should use the Oomph Eclipse installer. The N4JS project is listed under "Eclipse Projects/N4JS" This setup installs the correct Eclipse version, creates a new workspace and clones all projects into it (for details see below).

Eclipse Installer

The recommended way to install the Eclipse IDE and set up the workspace is to use the Eclipse Installer. This installer is to be downloaded from https://wiki.eclipse.org/Eclipse_Installer

For details, see the section Eclipse Installer in the design document.

Documentation

Build the N4JS IDE from command line

Ensure you have

  • Java 11

  • Maven 3.2.x and

  • Node.js 12.3.x (recommended).

installed on your system.

Clone the repository

git clone https://github.com/Eclipse/n4js.git

Change to the n4js folder:

cd n4js

Run the Maven build:

mvn clean verify

You may have to increase the memory for maven via export MAVEN_OPTS="-Xmx2048m" (Unix) or set MAVEN_OPTS="-Xmx2048m" (Windows).

Publish maven-tooling org.eclipse.n4js.releng.util

Note
For extending the N4JS-language in a different project, the org.eclipse.n4js.releng.util module needs to be published as a maven-plugin. You can deploy this SNAPSHOT-artifact to a local folder by providing the local-snapshot-deploy-folder-property pointing to an absolute path in the local file system:
mvn clean deploy -Dlocal-snapshot-deploy-folder=/var/lib/my/folder/local-mvn-deploy-repository

The existence of local-snapshot-deploy-folder will trigger a profile enabling the deploy-goal for the project org.eclipse.n4js.releng.util

License

Copyright (c) 2019 NumberFour AG and others.

All rights reserved. This program and the accompanying materials are made available under the terms of the Eclipse Public License v1.0 which accompanies this distribution, and is available at http://www.eclipse.org/legal/epl-v10.html

n4js's People

Contributors

bsmith-n4 avatar dbo avatar dependabot[bot] avatar eclipsewebmaster avatar emirazz avatar ev21 avatar exe-boss avatar gbastkowski avatar halitogunc avatar jean-andre-gauthier avatar jpilgrim avatar kduske-n4 avatar lbeurerkellner avatar mmews-n4 avatar mor-n4 avatar moreiser avatar rodrigoehlers avatar szarnekow avatar yoosiba avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

n4js's Issues

Content Assist doesn't reliably work in generator functions

The following code doesn't content assist the members of req:

class A {}
export public function* foo(req: A) { // removing export public fixes the problem 
    yield 5; // removing 5 fixes the problem
    req. // <-- content assist here ctrl+space
}

Probably a problem with our parameterized rules. In some cases, a wrong method name is generated. This rule name is created with information from the generated (Content Assist) parser, cf. https://github.com/eclipse/n4js/blob/master/plugins/org.eclipse.n4js.ui/src-gen/org/eclipse/n4js/ui/contentassist/antlr/N4JSParser.java#428
This leads to a non-existing method name: java.lang.NoSuchMethodException: eu.numberfour.n4js.ui.contentassist.CustomN4JSParser$CustomInternalN4JSParser.norm3_AssignmentExpression__Group_3__0()

Potential solutions:

  1. fix generated code (Xtext bug)
  2. avoid usage of parameterized rules by moving the yield/non-yield check to the validator (ASTStructureValidator)

However this may only be a consequential or different error, accidentally revealed by this problem.

(initial reporter: @mmews-n4 , comments: @jpilgrim

As a developer I want support for the ES 2018 syntax of spread operators in object literals

This refers to support in the syntax (in the grammar / parser).
The spread operator is currently supported in argument lists, array literals, etc. but not in object literals.

This is required by the transpiler, for example, in order to use spread operators in the output code.

Adjust:

  • Grammar,
  • AST to add property

Acceptance Criteria:

  • Support spread operator syntax
  • Add unsupported feature validation, since full support (i.e. type checking, transpiler, etc.) is not part of this task
  • Adjust ES6 test suite blacklist
  • Update lang-spec (follow-up not allowed, especially changing list of legal expressions in computed property/member names)

(moved from internal bug tracker, original reporter: @mor-n4)

As a user I want a consistent handling of implicit super types between class, interface

For classes the super type may be N4Object or Object. What happens if a class directly inheriting from Object has subclasses implementing an interface without a declared super interface?

Considerations

  • External classes and interfaces in .n4jsd files.
  • Scoping: it does not yet heed the rules for implicit super types of classes, cf. method MemberScopeProvider#members(ContainerType, EObject, boolean).
  • also consider the 4 cases of the following example:
interface I {}

// case #1
class C {}
// case #2
//class C extends Object {}
// case #3
//class C extends N4Object {}
// case #4
//class C extends Object implements I {}

// compare how the following code behaves for each of the cases above:

C.n4type;
var c: C;
c.xyz123();
var v1: N4Object = c;

I.n4type;
var i: I;
i.xyz123();
var v2: N4Object = i;

Acceptance Criteria

  • identify cases where interfaces behave differently than classes w.r.t. their implicit super type,
  • define & implement changes required,
  • update spec,
  • Method RuleEnvironmentExtensions.isN4Object(RuleEnvironment, TClass) should be consolidated (this method was implemented as a quick fix).

(moved from internal bug tracker, original reporter: @mor-n4 )

As a developer I want to align N4JS constructor super calls with ES6

As a developer I want to align N4JS constructor super calls with ES6.
In ES6, constructors of subclasses MUST explicitly call super constructor, even if that one is empty.

class C {}
class D extends C {	
	// XPECT FIXME errors --> "super() must be explicitly called"
	constructor() {	}
}
class E extends C {
	constructor() {
		// XPECT FIXME errors --> "super() must be called before accessing this"
		var x = this;
		super();
	}
}

class F extends C {
	constructor() {
		var x = 5;
		super();
	}
}

In ES6 it is a syntax error to have a super() call in the constructor of a class that does not extend another class:

class A {}
class B { // adding "extends A" here resolves the error
  constructor() {
    super(); // error: "super call is only allowed in derived constructor"
  }
}

N4JS does allow super calls in such cases.

Considerations

  • Should this be aligned and if so
  • How it should be implemented

Acceptance Criteria

  • Review ES6 specification and update N4JS specification accordingly.

(moved from internal bug tracker, original reporter: @jpilgrim)

As a developer I want to remove TypeName from code

TypeName won't be supported. In order for validation, the name must be visible (i.e. imported) – but then one do not need the name anymore. TypeName must be removed from code (it is already removed from the language specification).

(moved from internal bug tracker, original reporter: @jpilgrim)

As a developer I want a compact notation for structural Object-types (~{ })

Our current notations for structural object types is verbose:

var v: ~Object with { a:A, b:B }

Proposed syntax:

var v: ~{ a:A, b:B }

or same as TypeScript (preferred, these types are always structural anyway):

var v: { a:A, b:B }

TypeScript version may produce an ambiguity with function types:

var v0: {function ()}
var v1: { function }

Probably adjusting a syntactic predicate ( 'function' + '(' ) should fix that.

Maybe this simplified syntax cannot be allowed at all locations, in particular where we still use old "Java-like" type annotations.

In general, try to be as close to TypeScript as possible.

Note:

  • Possible pitfall in binding (ParameterizedTyperef)
  • Probably similar as Array vs. []

(moved from internal bug tracker, original reporter: @torstenkraemer)

As a developer I would like to declare abstract static members

Since statics are inherited by subclasses, it makes sense in some cases to have a protected abstract static member.

This would enforce child classes to implement this static member to be used in superclasses in a static context.

Example:

abstract class ABase {
    protected abstract static a();

    doA() {
        this.constructor.a();
    }
}

class A extends ABase {
    @Override
    protected static a() {
        console.log("doing a foo")
    }
    
    doSomething() {
        this.doA();
    }
}

class B extends ABase {
    @Override
    protected static a() {
        console.log("doing a bar")
    }
    
    doSomethingElse() {
        this.doA();
    }
}

(moved from internal bug tracker, original reporter: @arrowplum)

As a smith I need the n4js libraries to be compiled in "shipped code" plugin

As a smith I need the n4js libraries to be compiled in "shipped code" plugin so that the CI builds can be set up correctly.

Due to technical restrictions, we need a compiled copy of the n4js-libs in plugin n4js/plugins/org.eclipse.n4js.external.libraries/ (folder shipped-code). This is done via an MWE build
n4js/plugins/org.eclipse.n4js.external.libraries.update/src/org/eclipse/n4js/external/libraries/update/UpdateShippedCode.mwe2

The libraries were added as part of CQ-13620, but not the shipped code (which is a compiled copy).

Acceptance Criteria

  • compiled versions of n4js-libs are contained in n4js/plugins/org.eclipse.n4js.external.libraries/shipped-code

As a developer I want type aliases

In TypeScript, type aliases can be defined with keyword type, e.g.,

type Name = string;

This would be in particular useful for union and intersection types, and for function type definitions, e.g.

type callback = (int)=>string;

This must also be allowed in n4jsd files.

Clarify open questions, such as

  • use in API vs. implementation
  • structural typing
  • could they be chained (type alias on right hand side)
  • generic types
  • impact on type equality
  • when to resolve the alias, e.g., in error messages and hovers

In general, do some research. Try to specify feature as compatible to TypeScript as possible (at least similar syntax).

Acceptance Criteria

// XPECT noerrors --> 
type Name = string;

// XPECT errors --> "Type dog is not a recognized type" at "dog"
type Name = dog;
  • write spec
  • write tests
  • implement

(moved from internal bug tracker, original reporter: @jpilgrim)

As a developer I want support for ES6 Proxies

cf.
http://www.ecma-international.org/ecma-262/6.0/#sec-proxy-object-internal-methods-and-internal-slots
https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Proxy

More specifically, we need a proxy of some type to be the subtype of that type. That is, {{Proxy <: T}} to be always true.

Note that the proxy even "proxifies" the constructor (cf. node):

class A {}
> let a = new A();

> a.constructor
[Function: A]

> p = new Proxy(a, handler);
> p.constructor
[Function: A]

Acceptance Criteria

class A {}
class B {}

let p: Proxy<A>;
// XPECT noerrors -->
let a: A = p;
// XPECT errors --> "Proxy<A> is not a subtype of B"
let b: B = p;

(moved from internal bug tacker, original reporter: @mor-n4)

Replace hacky workaround in CustomN4JSParser#106

With the update to XText 2.11, a workaround was necessary to make some tests like GHOLD-92-LINKING_DIAGNOSTIC_import_missing_B.n4js.xt working. This workaround indicates a conceptually problem and thus should be solved by further investigating about the underlying problem. The goal is to remove the method CustomN4JSParser#initializeFor(AbstractRule).

As a developer I need methods of ObjectLiterals working with default initializers

Methods in ObjectLiterals were introduced by changing the grammar. However, the existing code base was not fully adapted to these methods. Hence, type inference does not work with methods correctly (see test 1a). The other examples refer to default initialisers of parameters which also have to be supported by this task.

Acceptance Critera:

Test 1:

class A {}
class B extends A {}
class C extends B {}
let c: C;

// Test 1a
// XPECT typeof 'p' --> B
let ol: ~Object with { m(B):void } = { void m(p ) {} } // p is any
ol;

// Test 1b
// X-PECT FIXME noerrors -->
// XPECT typeof 'p' --> union{B,C}
let ol1: ~Object with { m(B):void } = { void m(p = c) {} }
ol1;

Test 2:

let ol = {
    prop: "hello",

    // Test 2a
    // XPECT FIXME noerrors -->
    m1(p1 = this.prop) {},

    // Test 2b
    m2(p0, p1 = p0) {},
}
ol;

(moved from internal bug tracker, original reporter: @mmews-n4 )

As a smith I want to have a canonical form of composed types so that the associative law applies between two composed types.

Nesting is possible when using composed types. At the moment, these nested composed types are not transformed into a canonical form. Hence, errors occur when checking two composed types with regard to their inheritance. Using a canonical form can solve this issue. Depending on the type constraint solver, a DNF or KNF can be used, which also can be minimised. When minimising, also the inheritance relations might be taken into account to retrieve an even further minimised form.

Acceptance criteria

  • Composed types have a canonical form, e.g. (minimised?) DNF or KNF
  • Associative law applies on composed types

(moved from internal bug tracker, original reporter: @mmews-n4)

Cyclic references between files can confuse editor dirty state handling AND incremental builder / Xtext index

In case of cyclic references between a file A opened in an N4JS editor and some other file B, the editor might show outdated information for the remote file B in case an unsaved change in the editor (for file A) has an effect on the TModule information of file B. In such a case, the dirty state handling does not update the information obtained from the index for file B until the editor contents are saved. In addition, also the incremental builder and Xtext index can become inconsistent until file A is saved repeatedly.

Unfortunately, this is not only a problem of the dirty state handling because it also affects the incremental builder.

To reproduce, create a file A.n4js:

import {B} from "B";

export class A {
	static fieldA = 'some string';
}

let str: string = B.fieldB;

and a file B.n4js:

import {A} from "A";

export class B {
	static fieldB = A.fieldA;
}

Now perform a clean build and then

  • open file A.n4js in an N4JS editor (do not open file B.n4js).
  • change the string literal 'some string' to a number literal 42 (without saving!!).
  • now, an error is expected in the editor in the last line of file A.n4js (because the type of B.fieldB has now changed from string to number) but this error is not shown (Problem 1: inconsistent dirty state in editor -- but this may be correct, we do not build other files in dirty state).
  • save editor contents (i.e. save file A.n4js).
  • now, the editor shows the correct state (i.e. the error mentioned in step 3 shows up) but note that the incremental builder does not show this error, i.e. no error shown in Eclipse Problems View (Problem 2: inconsistent builder / Xtext index state). This is the real problem!
  • add an empty line to file A.n4js and save again.
  • now the error mentioned in step 4 shows up in the Eclipse Problems View as well.

As a smith I need two Xpect related files in N4JS repository

There are two files in NumberFour/n4js which were not added yet to eclipse/n4js since they contain code originally created by Moritz Eysholdt (@meysholdt), author of Xpect.

After analysis of both files, we (Jens and Moritz) came to the following conclusion:

  • ScopeXpectMethod: The originally imported file was called AbstractQnAwareScopingTest. This file was renamed and changed quite often and does contain almost no code of the orignal version (name is different, code is different, some "import statements" remained). We agreed to change copyright notice and remove author tag.
  • N4JSCommaSeparatedValuesExpectation is a customised version of CommaSeparatedValuesExpectationImpl. In this case, a fair amount of code written by Moritz can be identified. We therefore decided to add that file with a commit message including Moritz' sign-off (Also-by: Moritz Eysholdt <his mail address>)

Acceptance Criteria

  • Both files are added to the eclipse/n4js repository with appropriate copyright header and sign-off

Exception thrown when creating project via wizard

To reproduce this bug, do the following steps:

  • Start the IDE
  • Create a new project via New -> N4JS Project
  • In the console, java.lang.IllegalArgumentException is thrown
!STACK 0
java.lang.RuntimeException: java.lang.IllegalArgumentException: wrong number of arguments
	at org.eclipse.xtext.service.MethodBasedModule.invokeMethod(MethodBasedModule.java:138)
	at org.eclipse.xtext.service.MethodBasedModule.configure(MethodBasedModule.java:68)
	at org.eclipse.xtext.service.CompoundModule.configure(CompoundModule.java:35)
	at org.eclipse.xtext.service.AbstractGenericModule.configure(AbstractGenericModule.java:33)
	at org.eclipse.xtext.ui.DefaultUiModule.configure(DefaultUiModule.java:134)
	at org.eclipse.n4js.n4jsx.ui.N4JSXUiModule.configure(N4JSXUiModule.java:140)
	at com.google.inject.spi.Elements$RecordingBinder.install(Elements.java:223)
	at com.google.inject.spi.Elements.getElements(Elements.java:101)
	at com.google.inject.spi.Elements.getElements(Elements.java:92)
	at com.google.inject.util.Modules$RealOverriddenModuleBuilder$1.configure(Modules.java:172)
	at com.google.inject.AbstractModule.configure(AbstractModule.java:59)
	at com.google.inject.spi.Elements$RecordingBinder.install(Elements.java:223)
	at com.google.inject.spi.Elements.getElements(Elements.java:101)
	at com.google.inject.internal.InjectorShell$Builder.build(InjectorShell.java:133)
	at com.google.inject.internal.InternalInjectorCreator.build(InternalInjectorCreator.java:103)
	at com.google.inject.Guice.createInjector(Guice.java:95)
	at com.google.inject.Guice.createInjector(Guice.java:72)
	at com.google.inject.Guice.createInjector(Guice.java:62)
	at org.eclipse.n4js.n4jsx.ui.internal.N4JSXActivator.createInjector(N4JSXActivator.java:74)
	at org.eclipse.n4js.n4jsx.ui.internal.N4JSXActivator.getInjector(N4JSXActivator.java:62)
	at org.eclipse.n4js.n4jsx.ui.N4JSXExecutableExtensionFactory.getInjector(N4JSXExecutableExtensionFactory.java:31)
	at org.eclipse.xtext.ui.guice.AbstractGuiceAwareExecutableExtensionFactory.create(AbstractGuiceAwareExecutableExtensionFactory.java:51)
	at org.eclipse.core.internal.registry.ConfigurationElement.createExecutableExtension(ConfigurationElement.java:262)
	at org.eclipse.core.internal.registry.ConfigurationElementHandle.createExecutableExtension(ConfigurationElementHandle.java:55)
	at org.eclipse.xtext.builder.impl.RegistryBuilderParticipant$DeferredBuilderParticipant.initDelegate(RegistryBuilderParticipant.java:182)
	at org.eclipse.xtext.builder.impl.RegistryBuilderParticipant$DeferredBuilderParticipant.getDelegate(RegistryBuilderParticipant.java:173)
	at org.eclipse.n4js.ui.building.N4JSGenerateImmediatelyBuilderState.findJSBuilderParticipant(N4JSGenerateImmediatelyBuilderState.java:257)
	at org.eclipse.n4js.ui.building.N4JSGenerateImmediatelyBuilderState.doUpdate(N4JSGenerateImmediatelyBuilderState.java:180)
	at org.eclipse.xtext.builder.builderState.AbstractBuilderState.update(AbstractBuilderState.java:116)
	at org.eclipse.xtext.builder.impl.XtextBuilder.doBuild(XtextBuilder.java:287)
	at org.eclipse.n4js.ui.building.N4JSBuildTypeTrackingBuilder.doBuild(N4JSBuildTypeTrackingBuilder.java:77)
	at org.eclipse.xtext.builder.impl.XtextBuilder.fullBuild(XtextBuilder.java:319)
	at org.eclipse.xtext.builder.impl.XtextBuilder.build(XtextBuilder.java:155)
	at org.eclipse.core.internal.events.BuildManager$2.run(BuildManager.java:735)
	at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:42)
	at org.eclipse.core.internal.events.BuildManager.basicBuild(BuildManager.java:206)
	at org.eclipse.core.internal.events.BuildManager.basicBuild(BuildManager.java:246)
	at org.eclipse.core.internal.events.BuildManager$1.run(BuildManager.java:301)
	at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:42)
	at org.eclipse.core.internal.events.BuildManager.basicBuild(BuildManager.java:304)
	at org.eclipse.core.internal.events.BuildManager.basicBuildLoop(BuildManager.java:360)
	at org.eclipse.core.internal.events.BuildManager.build(BuildManager.java:383)
	at org.eclipse.core.internal.events.AutoBuildJob.doBuild(AutoBuildJob.java:144)
	at org.eclipse.core.internal.events.AutoBuildJob.run(AutoBuildJob.java:235)
	at org.eclipse.core.internal.jobs.Worker.run(Worker.java:55)
Caused by: java.lang.IllegalArgumentException: wrong number of arguments
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.eclipse.xtext.service.MethodBasedModule.invokeMethod(MethodBasedModule.java:136)
	... 44 more

As a developer I want extended type inference for some typical Javascript idioms (Array#reduce(), Map#constructor(), ...)

Type inference for some use cases of array literals had been postponed in Sep 2015 (because implications for performance were unclear and to first gain some more experience with the new type inference from summer 2015). In particular, this applies to:

  • Nested array literals
  • Array literals that should be inferred to IterableN<...> instead of Array<...>

However, this led to some common use cases of array literals not being well-supported. This task is about extending type inference for array literals to better support those use cases, as summarised in the following.

Array literals as values of an object literal with type expectation

interface I {}

class C {
	public expectations: ~Object with {
        technicalContainer: I;
        technicalContents: Array<I>;
    } = {
        technicalContainer: null,
        technicalContents: [] // TODO mor-n4: infer this!
    };
}

Consider bounded wildcard as constraint solution in case of empty array literal

class C {}

// [] should be inferred to Array<? extends C> XPECT FIXME noerrors -->
var x: ~Object with {prop: Array<? extends C>} = { prop: [] };

// works in simple case though XPECT noerrors -->
var empty:  Array<? extends C> = [];

Using array literals with || (and similar nesting)

This case seems to be working now (at least in the simple example below), but double check and investigate what exactly is going on:

function foo(arr: Array<string>) {
	var theArr: Array<string> = arr || [];
}

Maybe we have added support for this with a special tweak that will no longer be required after fixing the other cases here.

Similar cases that still do not work:

let arr1: Array<string> = []; // works
let arr2: Array<string> = ([]); // does not work
let arr3: Array<string> = 5<6 ? [] : []; // does not work

Inference of nested array literals with an expectation of IterableN

Common use case: constructor of ES6 Map.

class Map<KeyT, ValueT> extends Object implements Iterable<Iterable2<KeyT, ValueT>> {
    public constructor(arg: Iterable<Iterable2<KeyT, ValueT>>?) {}

    @Override
    public [Symbol.iterator](): Iterator<Iterable2<KeyT,ValueT>> {return null;}
}

// XPECT FIXME noerrors --> "Array<Array<union{number,string}>> is not a structural subtype of Iterable<Iterable2<string,number>>?: #iterator failed: {function():Iterator<Array<union{number,string}>>} is not a subtype of {function():Iterator<Iterable2<string,number>>}." at "[['a', 1]]"
var map1: Map<string, number> = new Map<string, number>([['a', 1]]);

// XPECT noerrors --> "Workaround for the above issue."
var map: Map<string, number> = new Map<string, number>([['a', 1] as Iterable2<string, number>]);

Better support for Array#map() (and similar methods in general), in particular chaining with Array#forEach(), etc.

For example:

class B { foo() {} }
function trans(a): B { return null; }

function processAs(arrA: Array<any>): void {
    // at the moment, Array<any> is inferred XPECT FIXME type of 'x' --> Array<B>
    // XPECT FIXME noerrors --> "Couldn't resolve reference to IdentifiableElement 'foo'." at "foo"
    arrA.map( a => trans(a) ).forEach( b => b.foo() );
    
    // work-around, for the time being:
    arrA.map( (a):B => trans(a) ).forEach( b => b.foo() );
};

NOTE: this will probably require that we improve our "poor man's" return type inference (i.e. infer return type of function from type of expressions of contained return statements) and support more recursion cases during AST traversal (or is there a simpler way to support the above use cases?). However, we might need something like this anyway, when we introduce default expressions for formal parameters.

(moved from internal bug tracker, original reporter: @mor-n4)

As a committer I want features to be correctly named and designed

As a committer I want features to be correctly named and designed so that they match the common Eclipse naming patterns.

Also some features seems superfluous. E.g., e.o.n.lang.sdk seems not necessary (we already have e.o.n.sdk). Same may be true for other features.

Acceptance Criteria

  • all features "x.y.z.sdk" were renamed to "x.y.z-feature
  • reduced number of features

As a user I want a nice Eclipse N4JS website

Depends on: Initial Eclipse Commit done.

  • change/set hyperlinks to (generated) html pages in the docs project
  • change Jenkins job
  • other changes as needed
  • Manual part of website is already prepared
    • download: see incubation mailing list: add link to N4 release and mark that accordingly
    • generated parts are to be "converted", i.e. Jenkins job adjusted

General idea:

  • manually created pages are added to Eclipse website repository
  • generated pages (from adoc) are added to gh-pages

(moved from internal bug tracker, original reporter: @mmews-n4)

As a developer I need validation for resources with duplicated FQNs

There is an issue with when having files with the same qualified name in the workspace.
Assume project with manifest section

Sources {
    source {
        "src", "src2"
    }
    external {
        "ext"
    }
    test {
        "tst"
    }
}

When this project has files src/n4/Foo.n4js, src2/n4/Foo.js, ext/n4/Foo.n4jsd, tst/n4/Foo.n4js all those will be compiled to src-gen/n4/Foo.js. Race condition here leads to undetermined runtime behaviour (of the compiled code).

This is not only a transpiler problem, as the Xtext index will be populated based on their module qualified name, which happens to be n4/Foo in all cases. A race condition here will lead to strange validation problems across whole workspace. Validation in detecting clashing FQNs is needed.

Acceptance Criteria

Should work as expected

  • Revise tests (and validation), consider at least the following cases:
    • different extensions
    • different source folders
    • all GH issues related to this issue
  • Revise specification

(moved from internal bug tracker, original reporter: @yoosiba )

As a developer I want a concise syntax for anonymous @StringBased enums

It would be nice to allow on-the-fly creation of anonymous @StringBased enums like so:

var abc: "A" | "B" | "C";
var ab: "A" | "B";

Note that these types might behave slightly differently than ordinary @StringBased enums (so, they may actually be a different kind of type). For example, based on the above code we might say
{{abc <: ab}}, which is not true for ordinary @StringBased enums.

Note also the similarity with algebraic types in functional languages (e.g. Haskell). So maybe it would be good to have a quick look at that before deciding on the exact concept we want to implement.

Acceptance Criteria

  • clarify scope (e.g. just special for string literals or have a more general concept?)
  • compare with other languages (esp. TypeScript)
  • implement
  • tests + spec update

(moved from internal bug tracker, original reporter: @mor-n4)

n4jsc ignores resources specified in manifest

The manifest allows for specifying resources, that is, folders with arbitrary resources.
When running a project from the IDE, these resource folders are added to the NODE_PATH path. The n4jsc does not also behave this way.

For example, see the following manifest:
https://github.com/jpilgrim/mdspex/blob/master/mdspex.tests/manifest.n4mf

and the relevant workaround: https://github.com/jpilgrim/mdspex/blob/master/mdspex.tests/src/org/mdspex/ResourceBasedTest.n4js#L58

Browser Runner Background

The browser solution depends a lot on the desired technical setup of the web app. In general,
a reasonable approach would be for a runner to point the web server to resources defined in the project. The web client can load resources through the web server.

(moved from internal issues, original reporter: @jpilgrim)

Cycles between classes (and const/static variables) not handled correctly at runtime

A class cannot be used in module before it is declared in that module:

class A {
	const x = new B();
}

class B extends A {}
console.log(A.x instanceof B); // prints: false

This does not work using System.js. A fix is required for the runtime or a compilation error must be issued.

Considerations

The following conditions prove problematic:

  • A and B are located in the same module - splitting up both classes into separate modules (with export and import) solves the problem.
  • B is declared after A, i.e. the following example fixes the problem:
class B extends A {}
class A {
	const x : B = new B();
}
console.log(A.x instanceof A);  // prints: false
console.log(A.x instanceof B);  // prints: true

Since ES6 class declarations aren't hoisted, a decision must be made regarding ES6 semantics and System.js whether classes shall behave statically like in Java or dynamically like in EcmaScript.

Acceptance Criteria

// XPECT FIXME output --> true
class A {
	const x = new B();
}

class B extends A {}
console.log(A.x instanceof B);

(moved from internal issues, original reporter: @jpilgrim)

As a smith I need to migrate from org.eclipse.xtext.junit4 to org.eclipse.xtext.testing

In Xtext, the platform-independent test utils have been moved from org.eclipse.xtext.junit4 to org.eclipse.xtext.testing. The classes in org.eclipse.xtext.junit4 are being deprecated in Xtext 2.11.

For the very most cases, an adaption of the MANIFEST.MF plus "organize imports" should do.

This task cannot be started before using Xtext 2.11 (because the new API won't be available before that).

(moved from internal bug tracker, original reporter: @meysholdt)

As a smith I want to refactor the upper/lower bound judgment to allow recursive resolution of types

We often take the upper bound of a type to "resolve" it, i.e. to prepare it for further inspection by getting rid of wildcards, ExistentialTypeRef, bound this types, etc. through replacement with their upper bound. Often we also have to resolve type variables in this way, which is not done by the upper bound judgment (this is what method TypeSystemHelper#resolveType() was added for).

However, this should be done recursively, because the upper bound of, for example, a type variable might again be a type variable which needs to be resolved (see TODO in method TypeSystemHelper#resolveType()).

Such recursive resolution of types requires a means to detect when a type is "stable", i.e. does no longer change through resolution. This could be done with an identity check on the type reference if(!) the upper/lower bound judgments would guarantee to return the identical type reference unchanged if there is no upper/lower bound which is non-equal to the input type reference (i.e. the upper/lower bound judgment must not create unnecessary copies).

Currently this is not the case and this task is about refactoring the upper/lower bound judgment accordingly and the change method TypeSystemHelper#resolveType() to recursively resolve the type reference until it is stable in the above sense.

Acceptance Criteria:

  • refactor upper/lower bound judgment
  • slightly change method TypeUtils#resolveTypeVariable() to return any if no upper bound is declared (for consistency with rule upperBoundWildcard in Xsemantics)
  • change method TypeSystemHelper#resolveType()
  • check all invocations of the upper bound judgment and replace them with a call to N4JSTypeSystem#resolveType() if that code actually wants to do a type resolution, instead of simply taking the upper bound
  • go through all uses of TypeVariable#declaredUpperBounds and check if it is a special handling that would better be implemented using the new TypeSystemHelper#resolveType() (there are several of these cases).

(moved from internal bug tracker, original reporter: @mor-n4)

As a smith I need to update about.html files after transferring initial 3rd-party-related things

As a smith I need to update about.html files after transferring 3rd-party-related things and recent changes to the Eclipse N4JS repo.

In order to simplify the FileChecker.java tool, we move all information currently found in third-party-txt to comments in the about dialog. The format is as follows:

<!--
THIRD-PARTY_PATH: project/relative/path/to.file
THIRD-PARTY_PATH: project/relative/path/to/folder/**
-->

Acceptance Criteria

  • about.html of all projects with 3rd party content contain description of this content
  • about.html of all projects with content copied from other Eclipse projects contain a comment line

As a developer I want meaningful icons where placeholders are used

As a developer I want meaningful icons where placeholders are used at the moment so that I can easily see what I'm doing.

The following icons are currently replaced by placeholders:

  • plugins/org.eclipse.n4js.xpect.ui/icons/xpect_run.png
  • plugins/org.eclipse.n4js.runner.nodejs.ui/icons/icon_runner_nodejs.png
  • plugins/org.eclipse.n4js.npmexporter.ui/icons/npm_export.png
  • docs/org.eclipse.n4js.spec/images/jira.png
  • plugins/org.eclipse.n4js.runner.chrome.ui/icons/icon_runner_chrome.png

Although we even got permission to use the npm logo, we cannot add that due to IP issues.
There are already some "forged" icons in the eclipse org rep (search: org:eclipse extension:gif extension:png extension:jpg size:<500 filename:logo filename:icon). We need to clarify that.

Acceptance Criteria

  • icons mentioned above have been replaced by meaningful icons

As a developer I want to write type parameters after method-/ function-names similar to TypeScript

Using generics with the Java syntax (and our current N4JS as well) is to prefix methods / functions with the type annotation:

export class A {
    public <V> method() : V { return null;  }
}
var x:A = new A().<A>method();

function <U> f1() :U { return null; }
var y:A = <A>f1();

As an improved version we want this to be

export class A {
    public method<V>() : V { return null;  }
}
var x:A = new A().method<A>();

function f1<U>() :U { return null; }
var y:A = f1<A>();

This would be compatible with TypeScript.

Remarks

  • we probably need to adjust the syntax allowing for both versions. Be careful not to to allow public <V>f<V>()...-- add a test for that as well
  • recognize the old style with a flag, e.g. javaStyle?='<' ... '>'. This should make validation simple

Acceptance Criteria

  • both versions are accepted
  • a warning is issued for old version
  • update N4JS spec accordingly

Xpect Tests

export class A {
    // XPECT warnings --> "Java-styled generic methods are deprecated" at "<V>"
    public <V> method() : V { return null;  }
}
  // XPECT warnings --> "Java-styled parameterized method calls are deprecated" at "<A>"
var x:A = new A().<A>method();

  // XPECT warnings --> "Java-styled generic functions are deprecated" at "<V>"
function <U> f1() :U { return null; }

  // XPECT warnings --> "Java-styled parameterized function calls are deprecated" at "<A>"
var y:A = <A>f1();

export class A {
    // XPECT nowarnings -->
    public method<V>() : V { return null;  }
}
// XPECT nowarnings -->
var x:A = new A().method<A>();

// XPECT nowarnings -->
function f1<U>() :U { return null; }
// XPECT nowarnings -->
var y:A = f1<A>();

Notes

  • we will create another task providing a quickfix for rewriting Java-style to new style (#1380)

As a developer I want "var" being validated as in ES5/ES6 and have the relation var vs. let/const behave as in ES6

Redeclaration of var

It was a deliberate decision to show more errors for re-declaration of "var" in N4JS than in ES5:

var a;
var a; // <-- error in N4JS but not in ES5

Now, after adding support for let/const, this is no longer required and it is preferable to stay closer to the ES5/6 standard (for the usual reasons). So no errors should be shown for re-declaration of "var".

Side note: another reason for changing this is that currently the N4JS "var" is even stricter (in some cases) than the ES6 "let", which is probably counter-intuitive for Javascript devs.

Relation between var versus let/const

When working on this, conflicts between var vs. let/const should be revisited. Currently, N4JS does not show errors in some cases where errors should be shown. However, implementations of ES6 behave very differently here. Here is a comparison of N4JS, V8 (node v5.7.1), and Babel:

// in the entire following code, N4JS only shows a single error (which is too few)

// V8: error (on second a)
// Babel: error
var top_a;
let top_a; // <-- this is the only error that currently shows up properly in N4JS


// V8: error (on second a)
// Babel: error
function foo01() {
	var a;
	let a;
}


// V8: error (on first a)
// Babel: ok
function foo11() {
  {
    var a;
    let a;
  }
}


// V8: error (on first a)
// Babel: ok
function foo12() {
	if(true) {
		var a;
		let a;
	}
}


// V8: error (on first a)
// Babel: ok
function foo13() {
	for(;;) {
		var a;
		let a;
	}
}


// V8: two errors (see below)
// Babel: ok
function foo21() {
	{
		var a;
		{
			var b; // --> error in V8
			
			let a;
			let b;
			let c;
			{
				var c; // --> error in V8
			}
		}
	}
}


// V8: two errors (see below)
// Babel: ok
function foo22() {
	if(true) {
		var a;
		if(true) {
			var b; // --> error in V8
			
			let a;
			let b;
			let c;
			if(true) {
				var c; // --> error in V8
			}
		}
	}
}


// V8: two errors (see below)
// Babel: ok
function foo23() {
	for(;;) {
		var a;
		for(;;) {
			var b; // --> error in V8
			
			let a;
			let b;
			let c;
			for(;;) {
				var c; // --> error in V8
			}
		}
	}
}


// V8: one error (see below)
// Babel: ok
function foo31() {
	for(var a;;) {
		let a;
	}
	for(let b;;) {
		var b; // --> error in V8
	}
	for(let c;;) {
		let c;
	}
}

As part if this task, it has to be decided how N4JS should behave (probably we want to go the stricter approach as V8 does).

(moved from internal bug tacker, original reporter: @mor-n4)

Type inference contains error suspected to be caused by proxy

The follow code produces an error:

export public class C {
	b: B;
	d = new D();
	g() {
		this.b = this.d; // Error: any is not a subtype of B.
	}
}

abstract class B {}

class D extends B {
	protected c: C;
	f() {
		this.c.g(); // removing this line solves the error
	}
}

That is, although field d of C is correctly inferred as D, the assignment causes an error. However, this only happens if method C.g() is called in D.f(), which should be completely independent.

The error is also removed when C.d is explicitly typed (e.g. d: D = new D()).
No error is shown in the error view.

Note:

The following example also demonstrates a way to remove the error by moving the class D before class C:

class D extends B {
	protected c: C;
	f() {
		this.c.g();
	}
}
class C {
	b: B;
	d  = new D();
	g() {
		this.b = this.d; // no error here
	}
}
abstract class B {}

Acceptance Criteria

export public class C {
	b: B;
	// at least correctly shown in outline view XPECT typeof d --> D
	d = new D();
	g() {
		// XPECT FIXME noerrors --> "any is not a subtype of B."
		this.b = this.d;
	}
}

abstract class B {}

class D extends B {
	protected c: C;
	f() {
		this.c.g();
	}
}

(moved from internal issues, original reporter: @jpilgrim)

As a developer I want to use a getter/setter pair in an Impl project where API demands field (and vice versa)

Should we allow to use a getter/setter pair in an Impl project where the API demands a field (and vice versa).

API project:

export public external class C {
	public string field;
}

Impl project:

export public class C {
	public string get field() {return null;}
	public set field(string p) {}
}

Acceptance criteria

  • Clarification if it is possible (what about subclasses of C in client code; when compiling them, transpiler doesn't know if super class has field or getter/setter pair; for example: "super.field" is disallowed in subclass if field is a field but allowed if field is a getter/setter)
  • If possible, clarification if it is desirable (what are pros/cons? discuss with stakeholders)
  • If desirable, implementation + tests! (not only project compare logic has to be adjusted; also stub generation has to be adjusted)

(moved from internal bug tracker, original reporter: @mor-n4)

Default workspace computation is inconsistent in Jenkins

Profile that activates default value for the workspace does not work well with the ant copied properties due to issue with diffirentiating between properties and environment variables.

E.g. when building in Jenkins logs will contain environment configuration

env.WORKSPACE=/media/data-2/jenkins_slave_home/workspace/multibranch_master-B3PDSWG7LQILACQEIB2YTGOQTSVJGT2JPZ6AQTIWZJGM6A3VJJ4Q

but then Ant will reconfigure property to

Setting project property: WORKSPACE -> /home/build

Problem is in the passing of the property in invocations like:

			<plugin>
				<!-- Executing the build as part of the integration test in a separate vm. -->
				<groupId>org.codehaus.mojo</groupId>
				<artifactId>exec-maven-plugin</artifactId>
				<version>${codehaus-exec-maven-plugin.version}</version>
				<configuration>
					<systemProperties>
						<WORKSPACE>${WORKSPACE}</WORKSPACE>

Where WORKSPACE property is activated by the default prop:

		<!-- Profile workspace-to-userhome is automatically activated if the property WORKSPACE is not set.
			 As a fall-back it sets it to ${user.home}  -->
		<profile>
			<id>workspace-to-userhome</id>
			<activation>
				<property>
					<name>!WORKSPACE</name>
				</property>
			</activation>
			<properties>
				<WORKSPACE>${user.home}</WORKSPACE>
			</properties>
		</profile>

Also note relevant discussion: https://stackoverflow.com/questions/8610980/checking-an-environment-variable-using-the-maven-antrun-plugin




One solution is to populate system property with env variable value in maven calls, e.g. " -DWORKSPACE=${env.WORKSPACE}" .

Alternative approach could be done by adding alternative implementation for handling default value.

Add generated documentation

The documentation that is used for the Eclipse help of the Eclipse N4JS IDE has to be generated from the already checked-in adoc files.

As a developer I need tagged template literals

Tagged templates are special functions retrieving the string parts of the template as first argument (array of string), succeeded by the values of the evaluated expressions. The returned value of the function is then the result of the template literal which is not necessarily a string.

The function itself should work out of the box. So, basically, this is a special form of a function call:

zCf. ECMAScript 2015 spec, chapter 12.3.7Tagged Templates
also see https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Template_literals

Acceptance Criteria

function tag(strings, p1, p2) {
  console.log(strings instanceof Array)
  console.log(typeof p1 == 'number')
  console.log(typeof p2 == 'number')
  return true;
}
// XPECT noerrors --> "string literals allow for embedded expressions" at "tag"
let x = tag`Hello ${1} world ${2*3}`;
console.log(typeof x == 'boolean')
  • updated spec
  • spec tests
  • transpiler (to be discussed)
  • implementation

(moved from internal bug tracker, original reporter: @jpilgrim)

As a developer I want the type of an overridden field to be used as type expectation (where appropriate)

The type of an overridden field should be used as type expectation for the initializer expression of the overriding field, in case the overriding field does not have a declared type.

Acceptance Criteria:

class A {}
class B extends A {}

class Cls1 {
	field: A;
}
class Cls2 extends Cls1 {
	// XPECT noerrors --> "Type of field Cls2.field must equal type of overridden field Cls1.field." at "field"
	@Override field = new B();
}
  • spec update

(moved from internal bug tracker, original reporter: @mor-n4 )

Update unicode support

The latest TP contains an updated com.ibm.icu bundle that supports a more recent version of the unicode standard. When I regenerate the Unicode.xtext, I see changes compared to the currently used version.

  • Does JS specify the unicode version, that it's supposed to be compatible to?
  • Should we migrate to JFlex which is a lexer with native support for unicode character classes?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.