Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.

Bug 341866

Summary: [xtend2] problems with create extensions
Product: [Modeling] TMF Reporter: Knut Wannheden <knut.wannheden>
Component: XtextAssignee: Project Inbox <tmf.xtext-inbox>
Status: CLOSED FIXED QA Contact:
Severity: normal    
Priority: P3 CC: sven.efftinge
Version: 2.0.0Flags: sven.efftinge: indigo+
Target Milestone: M7   
Hardware: All   
OS: All   
Whiteboard:

Description Knut Wannheden CLA 2011-04-05 02:25:42 EDT
The following Xtend2 class:

class Test {
	create new String() foo() {
		this + 'foo'
	}
}

is compiled to:

public class Test {
  private final Test _this = this;
  
  private final HashMap<ArrayList<?>,String> _createCache_foo = new HashMap<ArrayList<?>,String>();
  
  public String foo() {
    final ArrayList<?>_cacheKey = CollectionLiterals.newArrayList();
    if (_createCache_foo.containsKey(_cacheKey)) {
      return _createCache_foo.get(_cacheKey);
    }
    String _string = new String();
    String _this = _string;
    _createCache_foo.put(_cacheKey, _this);
    StringExtensions.operator_plus(_this, "foo");
    return _this;
  }
}

So the returned result is not "this + 'foo'" but just "this".

Further the 'return' keyword isn't handled properly. The following:

class Test {
	create new String() foo() {
		return this + 'foo'
	}
}

is compiled to:

  public String foo() {
    final ArrayList<?>_cacheKey = CollectionLiterals.newArrayList();
    if (_createCache_foo.containsKey(_cacheKey)) {
      return _createCache_foo.get(_cacheKey);
    }
    String _string = new String();
    String _this = _string;
    _createCache_foo.put(_cacheKey, _this);
    String _operator_plus = StringExtensions.operator_plus(_this, "foo");
    return _operator_plus;
    return _this; // COMPILE ERROR HERE
  }

Which doesn't compile due to the two consecutive returns.
Comment 1 Sven Efftinge CLA 2011-04-05 02:49:34 EDT
(In reply to comment #0)
> The following Xtend2 class:
> 
> class Test {
>     create new String() foo() {
>         this + 'foo'
>     }
> }
> 
> is compiled to:
> 
> public class Test {
>   private final Test _this = this;
> 
>   private final HashMap<ArrayList<?>,String> _createCache_foo = new
> HashMap<ArrayList<?>,String>();
> 
>   public String foo() {
>     final ArrayList<?>_cacheKey = CollectionLiterals.newArrayList();
>     if (_createCache_foo.containsKey(_cacheKey)) {
>       return _createCache_foo.get(_cacheKey);
>     }
>     String _string = new String();
>     String _this = _string;
>     _createCache_foo.put(_cacheKey, _this);
>     StringExtensions.operator_plus(_this, "foo");
>     return _this;
>   }
> }
> 
> So the returned result is not "this + 'foo'" but just "this".

That's the intended behavior

It doesn't make sense to use create extensions with immutable types.
Unfortunately we cannot tell statically whether a type is immutable or not.

The block can only do side effects to the created object.

> 
> Further the 'return' keyword isn't handled properly. The following:
> 
> class Test {
>     create new String() foo() {
>         return this + 'foo'
>     }
> }

That's an open issue.
Comment 2 Knut Wannheden CLA 2011-04-05 03:02:19 EDT
(In reply to comment #1)
> 
> It doesn't make sense to use create extensions with immutable types.
> Unfortunately we cannot tell statically whether a type is immutable or not.
> 
> The block can only do side effects to the created object.
> 

OK. Makes sense.
Comment 3 Sven Efftinge CLA 2011-04-05 03:23:23 EDT
pushed to master
Comment 4 Karsten Thoms CLA 2017-09-19 17:56:41 EDT
Closing all bugs that were set to RESOLVED before Neon.0
Comment 5 Karsten Thoms CLA 2017-09-19 18:07:31 EDT
Closing all bugs that were set to RESOLVED before Neon.0