Array<Cell<Key->Item>?> makeCellEntryArray<Key,Item>(Integer size)
    given Key satisfies Object
    given Item satisfies Object {

    return makeArray<Cell<Key->Item>?>(size, (Integer index) null);
}
Array<Cell<Element>?> makeCellElementArray<Element>(Integer size) {
    return makeArray<Cell<Element>?>(size, (Integer index) null);
}

Array<Cell<Key->Item>?> makeCellEntryArray<Key,Item>(Integer size)
    given Key satisfies Object
    given Item satisfies Object {

    return arrayOfSize<Cell<Key->Item>?>(size, null);
}
Array<Cell<Element>?> makeCellElementArray<Element>(Integer size) {
    return arrayOfSize<Cell<Element>?>(size, null);
}

Change makeArray -> arrayOfSize to fix compilation error


import ceylon.language.meta.declaration { Module }
import ceylon.test { test, assertEquals }
import ceylon.build.runner { findTopLevelAnnotatedGoals, findAnnotatedIncludes }
import mock.ceylon.build.runner.mock4 { include1, include2 }
import mock.ceylon.build.runner.mock4.subpackage { include3 }

test void shouldNotFindIncludeAnnotatedValuesIfNoPackage() {
    Module mod = `module mock.ceylon.build.runner.mock1`;
    value results = findTopLevelAnnotatedGoals(mod);
    assertEquals(results, []);
}

test void shouldNotFindIncludeAnnotatedValuesInEmptyPackages() {
    Module mod = `module mock.ceylon.build.runner.mock2`;
    value results = findTopLevelAnnotatedGoals(mod);
    assertEquals(results, []);
}

test void shouldNotFindIncludeAnnotatedValuesIfNoValuesAnnotatedWithIt() {
    Module mod = `module mock.ceylon.build.runner.mock3`;
    value results = findTopLevelAnnotatedGoals(mod);
    assertEquals(results, []);
}

test void shouldFindIncludeAnnotatedValues() {
    Module mod = `module mock.ceylon.build.runner.mock4`;
    value results = [].chain(findAnnotatedIncludes(mod));
    value expected = [`value include1`, `value include2`, `value include3`];
    assertEquals(results, expected);
}

import ceylon.build.runner {
	findTopLevelAnnotatedGoals,
	findAnnotatedIncludes
}
import ceylon.collection {
	HashSet
}
import ceylon.language.meta.declaration {
	Module,
	ValueDeclaration
}
import ceylon.test {
	test,
	assertEquals
}

import mock.ceylon.build.runner.mock4 {
	include1,
	include2
}
import mock.ceylon.build.runner.mock4.subpackage {
	include3
}

test void shouldNotFindIncludeAnnotatedValuesIfNoPackage() {
    Module mod = `module mock.ceylon.build.runner.mock1`;
    value results = findTopLevelAnnotatedGoals(mod);
    assertEquals(results, []);
}

test void shouldNotFindIncludeAnnotatedValuesInEmptyPackages() {
    Module mod = `module mock.ceylon.build.runner.mock2`;
    value results = findTopLevelAnnotatedGoals(mod);
    assertEquals(results, []);
}

test void shouldNotFindIncludeAnnotatedValuesIfNoValuesAnnotatedWithIt() {
    Module mod = `module mock.ceylon.build.runner.mock3`;
    value results = findTopLevelAnnotatedGoals(mod);
    assertEquals(results, []);
}

test void shouldFindIncludeAnnotatedValues() {
    Module mod = `module mock.ceylon.build.runner.mock4`;
    value results = [].chain(findAnnotatedIncludes(mod));
    value expected = [`value include1`, `value include2`, `value include3`];
    containSameElements(results, expected);
}

void containSameElements({ValueDeclaration*} actual, {ValueDeclaration*} expected) {
    assertEquals(HashSet { elements = actual; } , HashSet { elements = expected; });
}

Fix unstable test by not checking collections order


{FormattingOption+} formattingOptions = {
    FormattingOption {
    	"The indentation mode of the formatter.";
    	"IndentMode"; "indentMode"; /* = */ "Spaces(4)";
    }
};

{FormattingOption+} formattingOptions = {
    FormattingOption {
        "The indentation mode.";
        "IndentMode"; "indentMode"; /* = */ "Spaces(4)";
    },
    FormattingOption {
        "The maximum line length, or `null` for unlimited line length.";
        "Integer?"; "maxLineLength"; /* = */ "null";
    }
};

Add a "maxLineLength" formatting option.


interface SecondOrder<Box>
        given Box<Value> {
    shared formal Box<Float> createBox(Float float);
}
void takesCallableParamWithTypeParam(T f<T>(T t)) {}
value namedArgsInvocWithFunctionArgWithTypeParam = f {
    function f<T>(T t) {
        return t;
    }
};

Add test for named arg funs with type params

Part of #108.


import check {...}

void test_outer_inner_safety() {
  class Outer() {
    shared class Inner() { }
  }
  Outer? o = null;
  Outer.Inner? i1 = o?.Inner();
  Outer.Inner? cons() = o?.Inner();
  if (exists i1) {
    fail("i1 should be null");
  }
  check(className(cons)=="ceylon.language::JsCallable", "cons is Callable");
  Outer.Inner|Nothing i2 = cons();
  if (exists i2) {
    fail("i2 should not exist");
  }
}

import check {...}

void test_outer_inner_safety() {
  class Outer() {
    shared class Inner() { }
  }
  Outer? o = null;
  Outer.Inner? i1 = o?.Inner();
  Outer.Inner? cons() = o?.Inner();
  if (exists i1) {
    fail("i1 should be null");
  }
  check(className(cons)=="ceylon.language::JsCallable", "cons is Callable, " className(cons) "");
  Outer.Inner|Nothing i2 = cons();
  if (exists i2) {
    fail("i2 should not exist");
  }
}

Print obtained classname in error message


public class SimpleList<T> (T? head, SimpleList<T>? tail)
    satisfies Iterable<T>
{
    public T? car = head;
    public SimpleList<T> ? cdr = tail;

    public Iterator<T> iterator() {
        return SimpleIterator<T>(this);
    }

   public class SimpleIterator<T> (SimpleList<T> ? l)
       satisfies Iterator<T>
   {
        SimpleList<T> ? list = l;

        T? head() {
            if (exists list) {
                return list.car;
            } else {
                return null;
            }
        }

        Iterator<T> tail() {
            if (exists list) {
                return SimpleIterator<T>(list.cdr);
            } else {
                return SimpleIterator<T>(null);
            }
        }
    }
}

public class SimpleList<T> (T? head, SimpleList<T>? tail)
    satisfies Iterable<T>
{
    public Iterator<T> iterator() {
        return SimpleIterator<T>(this);
    }

   public class SimpleIterator<T> (SimpleList<T> ? list)
       satisfies Iterator<T>
   {
        T? head() {
            if (exists list) {
                return list.head;
            } else {
                return null;
            }
        }

        Iterator<T> tail() {
            if (exists list) {
                return SimpleIterator<T>(list.tail);
            } else {
                return SimpleIterator<T>(null);
            }
        }
    }
}

Fix optional types in back-end.

Fix optional types in back-end.


import ceylon.language.meta { modules }
import ceylon.language.meta.declaration { ClassDeclaration }

shared final annotation class TestAnnotation()
        satisfies OptionalAnnotation<TestAnnotation, ClassDeclaration> {
}

@test
shared void bug347() {
    for (value m in modules.list) {
        if(m.name.startsWith("org.apache")
            || m.name.startsWith("com.redhat.ceylon.maven-support")
            || m.name.startsWith("org.jboss.jandex")){
            continue;
        }
        for (value member in m.members) {
            value components = member.annotatedMembers<ClassDeclaration, TestAnnotation>();
            assert(components == []);
        }
    }
}

import ceylon.language.meta { modules }
import ceylon.language.meta.declaration { ClassDeclaration }

shared final annotation class TestAnnotation()
        satisfies OptionalAnnotation<TestAnnotation, ClassDeclaration> {
}

@test
shared void bug347() {
    for (value m in modules.list) {
        if(m.name.startsWith("org.apache")
            || m.name.startsWith("com.redhat.ceylon.maven-support")
            || m.name.startsWith("org.antlr")
            || m.name.startsWith("org.jboss.jandex")){
            continue;
        }
        for (value member in m.members) {
            value components = member.annotatedMembers<ClassDeclaration, TestAnnotation>();
            assert(components == []);
        }
    }
}

Make tests handle antlr module debug package


import ceylon.ast.core {
    Annotations,
    ValueDeclaration,
    DynamicModifier,
    LIdentifier,
    Type
}
import ceylon.ast.redhat {
    RedHatTransformer,
    valueDeclarationToCeylon,
    compileValueDeclaration
}
import com.redhat.ceylon.compiler.typechecker.tree {
    Tree {
        JAttributeDeclaration=AttributeDeclaration
    }
}

shared object valueDeclaration satisfies ConcreteTest<ValueDeclaration,JAttributeDeclaration> {

    String->ValueDeclaration construct(String->LIdentifier name, String->Type|DynamicModifier type, String->Annotations annotations)
            => "``annotations.key`` ``type.key`` ``name.key``;"->ValueDeclaration(name.item, type.item, annotations.item);

    shared String->ValueDeclaration lidValueDeclaration = construct(identifier.lidLIdentifier, dynamicModifier.dynamicModifier, annotations.emptyAnnotations);
    shared String->ValueDeclaration annotatedByValueDeclaration = construct(identifier.byLIdentifier, unionType.stringOrIntegerOrFloatUnionType, annotations.helloSharedByLucasAnnotations);

    compile = compileValueDeclaration;
    fromCeylon = RedHatTransformer.transformValueDeclaration;
    toCeylon = valueDeclarationToCeylon;
    codes = [lidValueDeclaration, annotatedByValueDeclaration];
}

import ceylon.ast.core {
    Annotations,
    ValueDeclaration,
    DynamicModifier,
    LIdentifier,
    Type,
    VariadicType
}
import ceylon.ast.redhat {
    RedHatTransformer,
    valueDeclarationToCeylon,
    compileValueDeclaration
}
import com.redhat.ceylon.compiler.typechecker.tree {
    Tree {
        JAttributeDeclaration=AttributeDeclaration
    }
}

shared object valueDeclaration satisfies ConcreteTest<ValueDeclaration,JAttributeDeclaration> {

    String->ValueDeclaration construct(String->LIdentifier name, String->Type|VariadicType|DynamicModifier type, String->Annotations annotations)
            => "``annotations.key`` ``type.key`` ``name.key``;"->ValueDeclaration(name.item, type.item, annotations.item);

    shared String->ValueDeclaration lidValueDeclaration = construct(identifier.lidLIdentifier, dynamicModifier.dynamicModifier, annotations.emptyAnnotations);
    shared String->ValueDeclaration annotatedByValueDeclaration = construct(identifier.byLIdentifier, unionType.stringOrIntegerOrFloatUnionType, annotations.helloSharedByLucasAnnotations);
    shared String->ValueDeclaration variadicValueDeclaration = construct(identifier.lidLIdentifier, variadicType.iterableOfStringPlusType, annotations.emptyAnnotations);

    compile = compileValueDeclaration;
    fromCeylon = RedHatTransformer.transformValueDeclaration;
    toCeylon = valueDeclarationToCeylon;
    codes = [lidValueDeclaration, annotatedByValueDeclaration];
}

Add tests for variadic value declaration


import assert { ... }

Element? find<Element>(Array<Element> a, Boolean f(Element x)) {
  for (Element e in a) {
    if (f(e)) {
      return e;
    }
  }
  return null;
}

void testAnonymous() {
  print("Testing anonymous functions...");
  value nums = array(1,2,3,4,5);
  //Test positional argument call
  variable value found := find(nums, (Integer i) i%2==0);
  if (exists i=found) {
    assert(i == 2, "anonfunc positional");
  } else { fail("anonfunc positional"); }
  //Named argument call
  found := find{
    function f(Integer i) {
      return i%2==0;
    }
    a=nums;
  };
  if (exists i=found) {
    assert(i == 2, "anonfunc named");
  } else { fail("anonfunc named"); }
}

import assert { ... }

Element? find<Element>(Array<Element> a, Boolean f(Element x)) {
  for (Element e in a) {
    if (f(e)) {
      return e;
    }
  }
  return null;
}

void testAnonymous() {
  print("Testing anonymous functions...");
  value nums = array(1,2,3,4,5);
  //Test positional argument call
  variable value found := find(nums, (Integer i) i%2==0);
  if (exists i=found) {
    assert(i == 2, "anonfunc positional");
  } else { fail("anonfunc positional"); }
  //Named argument call
  found := find{
    function f(Integer i) {
      return i%2==0;
    }
    a=nums;
  };
  if (exists i=found) {
    assert(i == 2, "anonfunc named");
  } else { fail("anonfunc named"); }

  //Gavin's test
   void callFunction(String f(Integer i)) {
       print(f(0));
   }

   function f(Integer i) {
       return (i+12).string;
   }
   callFunction(f);

   callFunction((Integer i) (i*3).string);

   callFunction {
       function f(Integer i) {
           return (i**2).string;
       }
   };

}

Add Gavin's tests for the 3 styles of higher-order function calling


import ceylon.language.meta.model {
    Attribute,
    Type
}
import ceylon.language.meta.declaration {
    ValueDeclaration,
    TypeParameter
}

"Contract for flattening the state of an instance of a class.
 This interface is implemented by a serialization library."
shared interface Deconstructor {

    "Adds the given type argument of the given type parameter to the flattened state."
    throws (`class AssertionError`,
        "if there is already a value for the given type argument")
    shared formal void putTypeArgument(TypeParameter typeParameter, Type typeArgument);

    "Adds the value of the given attribute to the flattened state."
    throws (`class AssertionError`,
        "if there is already a value for the given attribute")
    shared formal void putValue<Type>(ValueDeclaration attribute, Type referenced);
}

"The flattened state of an instance of a class.
 This interface is implemented by a serialization library."
shared interface Deconstructed
        satisfies {[ValueDeclaration, Anything]*} {

    "Get the type argument of the given type parameter"
    throws (`class AssertionError`,
        "if the type argument is missing")
    shared formal Type getTypeArgument(TypeParameter typeParameter);

    "Get the value of the given attribute."
    throws (`class AssertionError`,
        "if the value is missing")
    shared formal Type|Reference<Type> getValue<Type>(ValueDeclaration attribute);
}

import ceylon.language.meta.model {
    Attribute,
    Type
}
import ceylon.language.meta.declaration {
    ValueDeclaration,
    TypeParameter
}

"Contract for flattening the state of an instance of a class.
 This interface is implemented by a serialization library."
shared interface Deconstructor {

    "Adds the given type argument of the given type parameter to the flattened state."
    throws (`class AssertionError`,
        "if there is already a value for the given type argument")
    shared formal void putTypeArgument(TypeParameter typeParameter, Type typeArgument);

    "Adds the value of the given attribute to the flattened state."
    throws (`class AssertionError`,
        "if there is already a value for the given attribute")
    shared formal void putValue<Type>(ValueDeclaration attribute, Type referenced);

    shared formal void putArray<Element>(ValueDeclaration attribute, Array<Element> array);
}

"The flattened state of an instance of a class.
 This interface is implemented by a serialization library."
shared interface Deconstructed
        satisfies {[ValueDeclaration, Anything]*} {

    "Get the type argument of the given type parameter"
    throws (`class AssertionError`,
        "if the type argument is missing")
    shared formal Type getTypeArgument(TypeParameter typeParameter);

    "Get the value of the given attribute."
    throws (`class AssertionError`,
        "if the value is missing")
    shared formal Type|Reference<Type> getValue<Type>(ValueDeclaration attribute);

    shared formal Array<Element> array
    getArray<Element>(ValueDeclaration attribute);
}

Add support for persisting arrays.

S11N: Add support for persisting arrays.


"A formatter for the Ceylon programming language."
module ceylon.formatter "1.0.0" {
    shared import java.base "7";
    shared import com.redhat.ceylon.typechecker "1.0.0";
    shared import org.antlr.runtime "3.4";
    import ceylon.time "1.0.0";
    import ceylon.interop.java "1.0.0";
    import ceylon.collection "1.0.0";
    import ceylon.file "1.0.0";
}

"A formatter for the Ceylon programming language."
module ceylon.formatter "1.0.0" {
    shared import java.base "7";
    shared import com.redhat.ceylon.typechecker "1.0.0";
    shared import 'org.antlr-runtime' "3.4";
    import ceylon.time "1.0.0";
    import ceylon.interop.java "1.0.0";
    import ceylon.collection "1.0.0";
    import ceylon.file "1.0.0";
}

Update import of ANTLR runtime

Update import of ANTLR runtime


"Module that allows developping the Ceylon IDE in Ceylon"
by("David Festal")
module com.redhat.ceylon.eclipse.ui "1.1.1" {
    shared import com.redhat.ceylon.typechecker "1.1.1";
    shared import com.redhat.ceylon.model "1.1.1";
    shared import ceylon.collection "1.1.1";
    import ceylon.interop.java "1.1.1";
    shared import java.base "7";
}

"Module that allows developping the Ceylon IDE in Ceylon"
by("David Festal")
native("java")
module com.redhat.ceylon.eclipse.ui "1.1.1" {
    shared import com.redhat.ceylon.typechecker "1.1.1";
    shared import com.redhat.ceylon.model "1.1.1";
    shared import ceylon.collection "1.1.1";
    import ceylon.interop.java "1.1.1";
    shared import java.base "7";
}

Add the required native annotation

Add the required native annotation


"Given two streams, form a new stream by applying a
 function to the arguments in the given streams. The
 length of the resulting stream is the length of
 the shorter of the two given streams.

 Thus:

     mapPairs(xs,ys,fun)[i]==fun(xs[i],ys[i])

 for every `0<=i<min({xs.size,ys.size})`."
shared {Result*} mapPairs<Result,FirstArgument,SecondArgument>(
    Result collecting(FirstArgument firstArg, SecondArgument secondArg),
    {FirstArgument*} firstArguments,
    {SecondArgument*} secondArguments
) {
    object iterable satisfies {Result*} {
        shared actual Iterator<Result> iterator() {
            value first = firstArguments.iterator();
            value second = secondArguments.iterator();
            object iterator satisfies Iterator<Result> {
                shared actual Result|Finished next() {
                    if (!is Finished firstArg=first.next(),
                        !is Finished secondArg=second.next()) {
                        return collecting(firstArg,secondArg);
                    }
                    else {
                        return finished;
                    }
                }
            }
            return iterator;
        }
    }
    return iterable;
}

"Given two streams, form a new stream by applying a
 function to the arguments in the given streams. The
 length of the resulting stream is the length of
 the shorter of the two given streams.

 Thus:

     mapPairs(fun,xs,ys)[i]==fun(xs[i],ys[i])

 for every `0<=i<min({xs.size,ys.size})`."
shared {Result*} mapPairs<Result,FirstArgument,SecondArgument>(
    Result collecting(FirstArgument firstArg, SecondArgument secondArg),
    {FirstArgument*} firstArguments,
    {SecondArgument*} secondArguments
) {
    object iterable satisfies {Result*} {
        shared actual Iterator<Result> iterator() {
            value first = firstArguments.iterator();
            value second = secondArguments.iterator();
            object iterator satisfies Iterator<Result> {
                shared actual Result|Finished next() {
                    if (!is Finished firstArg=first.next(),
                        !is Finished secondArg=second.next()) {
                        return collecting(firstArg,secondArg);
                    }
                    else {
                        return finished;
                    }
                }
            }
            return iterator;
        }
    }
    return iterable;
}

Fix wrong order of arguments in doc

Fix wrong order of arguments in doc


import ceylon.buffer.codec {
    buildCodecLookup
}

"A mapping of all supported character sets.

 Currently this lists contains:

 - ASCII
 - ISO 8859 1
 - UTF-8
 - UTF-16
 "
shared Map<String,Charset> charsetsByAlias = buildCodecLookup {
    utf8
};

import ceylon.buffer.codec {
    buildCodecLookup
}

"A mapping of all supported character sets.

 Currently this lists contains:

 - ASCII
 - ISO 8859 1
 - UTF-8
 - UTF-16
 "
shared Map<String,Charset> charsetsByAlias = buildCodecLookup {
    utf8,
    utf16,
    iso_8859_1,
    ascii
};

Add missing charsets to charsetsByAlias

Add missing charsets to charsetsByAlias


doc "Creates a `Map` that contains the `Iterable`'s
     elements, grouped in `Sequence`s under the
     keys provided by the grouping function."
shared Map<Group, {Element+}> group<Group, Element>({Element*} elements,
    "A function that returns the key under which to group the
     specified element."
    Group grouping(Element element)) given Group satisfies Object {

    /*
    We've no idea how long the iterable is, nor how selective the grouping
    function is, so it's really had to accurately estimate the size of the
    HashMap.
    */
    value map = HashMap<Group, SequenceBuilder<Element>>() ;

    for (Element element in elements) {
        Group group = grouping(element);

        value sb = map.get(group);
        if (is SequenceBuilder<Element> sb) {
            sb.append(element);
        } else {
            map.put(group, SequenceBuilder<Element>().append(element));
        }
    }

    print(map);

    Sequence<Element> fn(Group key, SequenceBuilder<Element> item) {
        value sequence = item.sequence;
        assert(is Sequence<Element> sequence);
        return sequence;
    }

    return map.mapItems(fn);

}

doc "Creates a `Map` that contains the `Iterable`'s
     elements, grouped in `Sequence`s under the
     keys provided by the grouping function."
shared Map<Group, {Element+}> group<Group, Element>({Element*} elements,
    "A function that returns the key under which to group the
     specified element."
    Group grouping(Element element)) given Group satisfies Object {

    /*
    We've no idea how long the iterable is, nor how selective the grouping
    function is, so it's really had to accurately estimate the size of the
    HashMap.
    */
    value map = HashMap<Group, SequenceBuilder<Element>>() ;

    for (Element element in elements) {
        Group group = grouping(element);

        value sb = map.get(group);
        if (is SequenceBuilder<Element> sb) {
            sb.append(element);
        } else {
            map.put(group, SequenceBuilder<Element>().append(element));
        }
    }

    Sequence<Element> fn(Group key, SequenceBuilder<Element> item) {
        value sequence = item.sequence;
        assert(is Sequence<Element> sequence);
        return sequence;
    }

    return map.mapItems(fn);

}

Remove accidental call to print()

Remove accidental call to print()


import check { ... }

shared class AliasingClass() {
    shared interface AliasingIface {
        shared Boolean aliasingIface() { return true; }
    }
    shared class AliasingInner() {
        shared Boolean aliasingInner() { return true; }
    }
}

class AliasingSubclass() extends AliasingClass() {
    shared class InnerAlias() = AliasingInner;
    shared class SubAlias() extends InnerAlias() {}

    shared Boolean aliasingSubclass() {
        return SubAlias().aliasingInner();
    }
    shared interface AliasedIface = AliasingIface;
}

class AliasingSub2() extends AliasingSubclass() {
    shared AliasedIface iface {
        object aliased satisfies AliasedIface {
        }
        return aliased;
    }
}

void testAliasing() {
    print("testing type aliases");
    check(AliasingSubclass().aliasingSubclass(), "Aliased member class");
    class InnerSubalias() = AliasingSubclass;
    check(InnerSubalias().aliasingSubclass(), "Aliased top-level class");
    interface AliasedIface2 = AliasingClass.AliasingIface;
    Boolean use(AliasedIface2 aif) { return aif.aliasingIface(); }
    check(use(AliasingSub2().iface), "Aliased member interface");

}

import check { ... }

alias Strinteger = String|Integer;

shared class AliasingClass() {
    shared interface AliasingIface {
        shared Boolean aliasingIface() { return true; }
    }
    shared class AliasingInner() {
        shared Boolean aliasingInner() { return true; }
    }
}

class AliasingSubclass() extends AliasingClass() {
    shared class InnerAlias() = AliasingInner;
    shared class SubAlias() extends InnerAlias() {}

    shared Boolean aliasingSubclass() {
        return SubAlias().aliasingInner();
    }
    shared interface AliasedIface = AliasingIface;
}

class AliasingSub2() extends AliasingSubclass() {
    shared AliasedIface iface {
        object aliased satisfies AliasedIface {
        }
        return aliased;
    }
}

void testAliasing() {
    print("testing type aliases");
    check(AliasingSubclass().aliasingSubclass(), "Aliased member class");
    class InnerSubalias() = AliasingSubclass;
    check(InnerSubalias().aliasingSubclass(), "Aliased top-level class");
    interface AliasedIface2 = AliasingClass.AliasingIface;
    Boolean use(AliasedIface2 aif) { return aif.aliasingIface(); }
    check(use(AliasingSub2().iface), "Aliased member interface");
    Strinteger xxxxx = 5;
    check(is Integer xxxxx, "Type alias");
}

Add simple test for type alias

Add simple test for type alias


interface SecondOrder<Box>
        given Box<Value> {
    shared formal Box<Float> createBox(Float float);
}
void takesCallableParamWithTypeParam(T f<T>(T t)) {}
value namedArgsInvocWithFunctionArgWithTypeParam = f {
    function f<T>(T t) {
        return t;
    }
};
value anonymousGenericFunction = <T>(T t) => t;

Add test for generic anonymous functions

Part of #108.


import ceylon.html {
	Head,
	Body,
	Html
}
import ceylon.markdown.core {
	Document
}

"Render Markdown as a complete HTML document. This method returns an [[Html]] object.

     value html = renderCompleteHtml(tree);"
shared Html renderCompleteHtml(Document document) => Html {
	Head { },
	Body {
		children = HtmlVisitor().visitDocument(document);
	}
};

"Render Markdown as a list of HTML elements. This method returns a sequence.

     value nodes = renderPartialHtml(tree);"
shared HtmlChildren[] renderPartialHtml(Document document)
		=> HtmlVisitor().visitDocument(document);

import ceylon.html {
	Head,
	Body,
	Html,
	Meta
}
import ceylon.markdown.core {
	Document
}

"Render Markdown as a complete HTML document. This method returns an [[Html]] object
 using the `utf-8` charset.

     value html = renderCompleteHtml(tree);"
shared Html renderCompleteHtml(Document document) => Html {
	Head {
		Meta { charset="utf-8"; }
	},
	Body {
		children = HtmlVisitor().visitDocument(document);
	}
};

"Render Markdown as a list of HTML elements. This method returns a sequence.

     value nodes = renderPartialHtml(tree);"
shared HtmlChildren[] renderPartialHtml(Document document)
		=> HtmlVisitor().visitDocument(document);

Use the `utf-8` charset for html

Use the `utf-8` charset for html


void decLiterals() {
    value clM = `module ceylon.language`;
    value clP = `package ceylon.language`;
    value stringC = `class String`;
    value iterableI = `interface Iterable`;
    value aliasA = `alias Alias`;
    value givenG = `given Given`;
    value nullV = `value null`;
    value identityF = `function identity`;
    value newN = `new Constructor`;

    value currentM = `module`;
    value currentP = `package`;
    value currentC = `class`;
    value currentI = `interface`;
}

void decLiteralsWithoutBackticks() {
    value clM = module ceylon.language;
    value clP = package ceylon.language;
    value stringC = class String;
    value iterableI = interface Iterable;
    value aliasA = alias Alias;
    value givenG = given Given;
    value nullV = value null;
    value identityF = function identity;
    value newN = new Constructor;

    value currentM = module;
    value currentP = package;
    value currentC = class;
    value currentI = interface;
}

Add test for backtick-less meta literals

Just copied from the existing test, with all backticks removed.

Part of #143.


interface SecondOrder<Box>
        given Box<Value> {
    shared formal Box<Float> createBox(Float float);
}
void takesCallableParamWithTypeParam(T f<T>(T t)) {}
value namedArgsInvocWithFunctionArgWithTypeParam = f {
    function f<T>(T t) {
        return t;
    }
};
value anonymousGenericFunction = <T>(T t) => t;
class C() {
    parameterizedExpressionWithTypeParams<T>(T t) => t;
}

Add test for parameterized exprs with type params

Another part of #108 that already works without having to change
anything. Looks like ParameterizedException’s default walker order works
for us.


import ceylon.build.task { Goal, GoalSet }
import ceylon.collection { LinkedList }

"An interactive console."
void console({<Goal|GoalSet>+} goals) {
    value exitMessages = LazyMap<Integer, String>({
        exitCodes.success->"Success",
        exitCodes.dependencyCycleFound->"Dependency Cycle Found",
        exitCodes.invalidGoalFound->"Invalid goal found",
        exitCodes.duplicateGoalsFound->"Duplicate goals found",
        exitCodes.noGoalToRun->"No goal to run",
        exitCodes.errorOnTaskExecution->"Error on task execution"
    });
    print("Available goals: ``mergeGoalSetsWithGoals(goals)``");
    print("Enter Ctrl + D to quit");
    while (true) {
        process.write("> ");
        String? rawLine = process.readLine(); // workaround for https://github.com/ceylon/ceylon.language/issues/372
        if (is Null rawLine) {
            process.writeLine();
            return;
        }
        assert(exists rawLine);
        String line = rawLine.trimmed;
        value result = runEngine(goals,"",line.split().sequence);
        assert(exists msg = exitMessages[result.exitCode]);
        print(msg);
    }
}

import ceylon.build.task { Goal, GoalSet }
import ceylon.collection { HashMap }

"An interactive console."
void console({<Goal|GoalSet>+} goals) {
    value exitMessages = HashMap<Integer, String>({
        exitCodes.success->"Success",
        exitCodes.dependencyCycleFound->"Dependency Cycle Found",
        exitCodes.invalidGoalFound->"Invalid goal found",
        exitCodes.duplicateGoalsFound->"Duplicate goals found",
        exitCodes.noGoalToRun->"No goal to run",
        exitCodes.errorOnTaskExecution->"Error on task execution"
    });
    print("Available goals: ``mergeGoalSetsWithGoals(goals)``");
    print("Enter Ctrl + D to quit");
    while (true) {
        process.write("> ");
        String? rawLine = process.readLine(); // workaround for https://github.com/ceylon/ceylon.language/issues/372
        if (is Null rawLine) {
            process.writeLine();
            return;
        }
        assert(exists rawLine);
        String line = rawLine.trimmed;
        value result = runEngine(goals,"",line.split().sequence);
        assert(exists msg = exitMessages[result.exitCode]);
        print(msg);
    }
}

Use HashMap instead of LazyMap

Use HashMap instead of LazyMap


import check {...}

shared void test() {
    Boolean a = true;
    Boolean b = false;
    variable value count := 0;
    if (a && b) {
        fail("WTF?");
    } else if (a || b) {
        check(a||b, "boolean 1");
        count++;
    }
    String? c = "X";
    String? d = null;
    if (exists c && exists d) {
        fail("WTF exists");
    } else if (exists c1=c, exists c1[0]) {
        check(c1 == "X", "exists");
        count++;
    }
    String|Integer e = 1;
    if (is Integer e && exists d) {
        fail("WTF is");
    } else if (is Integer e, exists c) {
        check(e>0, "is");
        count++;
    }
    String[] f = {"a","b","c"};
    Integer[] g = {};
    if (nonempty f && nonempty g) {
        fail("WTF nonempty");
    } else if (nonempty f, nonempty f.first) {
        check(f.first.uppercased=="A", "nonempty");
        count++;
    }
    check(count==4, "some conditions were not met: " count " instead of 4");
    results();
}

import check {...}

shared void test() {
    Boolean a = true;
    Boolean b = false;
    variable value count := 0;
    if (a && b) {
        fail("WTF?");
    } else if (a || b) {
        check(a||b, "boolean 1");
        count++;
    }
    String? c = "X";
    String? d = null;
    if (exists c && exists d) {
        fail("WTF exists");
    } else if (exists c1=c, exists c1[0]) {
        check(c1 == "X", "exists");
        count++;
    }
    String|Integer e = 1;
    if (is Integer e && exists d) {
        fail("WTF is");
    } else if (is Integer e, exists c) {
        check(e>0, "is");
        count++;
    }
    String[] f = {"a","b","c"};
    Integer[] g = {};
    if (nonempty f && nonempty g) {
        fail("WTF nonempty");
    } else if (nonempty f, nonempty f.first) {
        check(f.first.uppercased=="A", "nonempty");
        count++;
    }
    check(count==4, "some conditions were not met: " count " instead of 4");
    Void zz = 1;
    assert(is Integer zz2=zz, zz2 > 0);
    check(zz2==1, "special -> boolean");
    //and now some comprehensions
    Sequence<Integer?> seq1 = { 1, 2, 3, null, 4, 5, null, 6, 7, null, 10};
    check({ for (i in seq1) if (exists i, i%2==0) i*10 }=={20,40,60,100},"comprehension [1]");
    results();
}

Test condition list with comprehensions

Test condition list with comprehensions


interface SecondOrder<Box>
        given Box<Value> {
    shared formal Box<Float> createBox(Float float);
}
void takesCallableParamWithTypeParam(T f<T>(T t)) {}
value namedArgsInvocWithFunctionArgWithTypeParam = f {
    function f<T>(T t) {
        return t;
    }
};
value anonymousGenericFunction = <T>(T t) => t;
class C() {
    parameterizedExpressionWithTypeParams<T>(T t) => t;
}

interface SecondOrder<Box>
        given Box<Value> {
    shared formal Box<Float> createBox(Float float);
}
void takesCallableParamWithTypeParam(T f<T>(T t)) {}
value namedArgsInvocWithFunctionArgWithTypeParam = f {
    function f<T>(T t) {
        return t;
    }
};
value anonymousGenericFunction = <T>(T t) given T satisfies Anything => t;
class C() {
    parameterizedExpressionWithTypeParams<T>(T t) => t;
}

Add test for anon functions with type constraints

Part of #108.


void characters() {
    value c = `a`;
    assert(c.lowercase, "lowercase char");
    assert(!c.uppercase, "lowercase char");
    assert(`A`.uppercase, "uppercase char");
    assert(!`A`.lowercase, "uppercase char");
    assert(c.uppercased==`A`, "uppercased char");
    assert(`A`.lowercased==`a`, "lowercased char");
    assert(c.string=="a", "character string");
    assert(!c.whitespace, "character not whitespace");
    assert(!c.digit, "character not whitespace");
    assert(` `.whitespace, "character whitespace");
    assert(`1`.digit, "character digt");
    assert(`a`<`z`, "char order");
    assert(`a`.successor==`b`, "char successor");
    assert(`Z`.predecessor==`Y`, "char predecessor");

    variable value i:=0;
    for (x in `a`..`z`) {
        i:=i+1;
        assert(x>=`a`&&x<=`z`, "character range");
    }
    assert(i==26, "character range");

    assert(c.integer.character==c, "integer/character conversion");
    assert(69.character.integer==69, "integer/character conversion");

}

void characters() {
    value c = `a`;
    assert(c.lowercase, "lowercase char");
    assert(!c.uppercase, "lowercase char");
    assert(`A`.uppercase, "uppercase char");
    assert(!`A`.lowercase, "uppercase char");
    assert(c.uppercased==`A`, "uppercased char");
    assert(`A`.lowercased==`a`, "lowercased char");
    assert(c.string=="a", "character string");
    assert(!c.whitespace, "character not whitespace");
    assert(!c.digit, "character not whitespace");
    assert(` `.whitespace, "character whitespace");
    assert(`1`.digit, "character digt");
    assert(`a`<`z`, "char order");
    assert(`a`.successor==`b`, "char successor");
    assert(`Z`.predecessor==`Y`, "char predecessor");
    assert(`\t`.integer==9, "escaped characters 1");
    assert(`\\`.integer==92, "escaped characters 2");
    assert(`\``.integer==96, "escaped characters 3");

    variable value i:=0;
    for (x in `a`..`z`) {
        i:=i+1;
        assert(x>=`a`&&x<=`z`, "character range");
    }
    assert(i==26, "character range");

    assert(c.integer.character==c, "integer/character conversion");
    assert(69.character.integer==69, "integer/character conversion");

}

Add tests for escaped character literals


import java.nio {
    JByteBuffer=ByteBuffer
}
import java.lang {
    ByteArray
}

shared {Byte*} toBytes(JByteBuffer[] jByteBufferArray) =>
     jByteBufferArray.flatMap((JByteBuffer element) => collectBytes(element));

{Byte*} collectBytes(JByteBuffer jByteBuffer) {
    ByteArray array = ByteArray(jByteBuffer.remaining()); //TODO can we do without new array?
    jByteBuffer.get(array);
    return array.iterable;
}

import java.nio {
    JByteBuffer=ByteBuffer
}
import java.lang {
    ByteArray
}

shared {Byte*} toBytes(JByteBuffer[] jByteBufferArray) =>
     jByteBufferArray.flatMap((JByteBuffer element) => collectBytes(element));

{Byte*} collectBytes(JByteBuffer jByteBuffer) {
    return jByteBuffer.array().iterable;
}

Remove creation of new array.

Remove creation of new array.


/*
 * Copyright 2011 Red Hat Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
void run(){
    print("Look, Ma! No module!");
}

/*
 * Copyright 2011 Red Hat Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
shared void run(){
    print("Look, Ma! No module!");
}

Fix for the JS backend: made run method shared


"Something that can go through a transition and is meant to
 be be fulfilled or rejected."
by("Julien Viet")
shared interface Resolver<in Value> {

    "Fulfills the promise with a value or a promise to the
     value."
    shared formal void fulfill(Value|Promise<Value> val);

    "Rejects the promise with a reason."
    shared formal void reject(Throwable reason);

    "Either fulfill or reject the promise"
    shared void resolve(Value|Promise<Value>|Throwable val) {
      if (is Value|Promise<Value> val) {
        fulfill(val);
      } else {
        assert(is Throwable val);
        reject(val);
      }
    }
}

"Something that can go through a transition and is meant to
 be be fulfilled or rejected."
by("Julien Viet")
shared interface Resolver<in Value> {

    "Fulfills the promise with a value or a promise to the
     value."
    shared formal void fulfill(Value|Promise<Value> val);

    "Rejects the promise with a reason."
    shared formal void reject(Throwable reason);

    "Either fulfill or reject the promise"
    shared void resolve(Value|Promise<Value>|Throwable val) {
      if (is Value|Promise<Value> val) {
        fulfill(val);
      } else {
        reject(val);
      }
    }
}

Make run with latest ceylon

Make run with latest ceylon


//Array tests
void testArrays() {
    assert(!nonempty arrayOfNone(), "arrayOfNone");
    value a1 = arrayOfSome({1});
    //assert(nonempty a1, "nonempty array");
    assert(a1.size==1, "array.size");
    assert(a1[0] exists, "array[0]");
    assert(!a1.empty, "array.empty");
    assert(a1.hash==1, "array.hash");
    a1.setItem(0,10);
    if (exists i=a1[0]) {
        assert(i==10, "array.setItem");
    } else { fail("array.setItem"); }
    a1.setItem(0,null);
    if (exists i=a1[0]) {
        fail("array.setItem (null)");
    }
}

//Array tests
void testArrays() {
    assert(!nonempty array(), "arrayOfNone");
    value a1 = array(1);
    assert(nonempty a1, "nonempty array");
    assert(a1.size==1, "array.size");
    assert(a1[0] exists, "array[0]");
    assert(!a1.empty, "array.empty");
    assert(a1.hash==1, "array.hash");
    a1.setItem(0,10);
    if (exists i=a1[0]) {
        assert(i==10, "array.setItem");
    } else { fail("array.setItem"); }
    a1.setItem(0,null);
    if (exists i=a1[0]) {
        fail("array.setItem (null)");
    }
    value a2=array(1,2,3);
    value a3=arrayOfSome({1,2,3});
    assert(a2==a3, "array.equals");
    assert(a2.size==a3.size, "array.size");
    assert(nonempty a2, "nonempty array 2");
    a2.setItem(0,10);
    a3.setItem(0,null);
    if (exists i=a2[0]) {
        assert(i==10, "array.setItem 2");
    } else { fail("array.setItem 2"); }
    if (exists i=a3[0]) {
        fail("array.setItem (null) 2");
    }
}

Complete the array tests (which now pass with flying colors)


by ("Stéphane Épardaud", "Alex Szczuczko")
module ceylon.buffer "1.2.1" {
    import ceylon.collection "1.2.1";
    native ("jvm") import java.base "7";
    native ("jvm") import java.tls "7";
    native ("jvm") import ceylon.interop.java "1.2.1";
}

"This module defines character sets, for encoding and decoding bytes to
 strings, as well as buffers of bytes and characters for input/output."
by ("Stéphane Épardaud", "Alex Szczuczko")
module ceylon.buffer "1.2.1" {
    import ceylon.collection "1.2.1";
    native ("jvm") import java.base "7";
    native ("jvm") import ceylon.interop.java "1.2.1";
}

Remove java.tls import from ceylon.buffer


Anything ifExpression =
        if (true || false)
        then 1
        else 2;
void ifExpr() {
    print(if (true) then 1 else 0);
}

Update if expressions test for changed indentation

See 681239e and #104.


import ceylon.ast.core {
    Annotations,
    ConstructorDefinition,
    Declaration,
    ExtendedType,
    Parameter,
    Parameters,
    Statement
}

"""Creates a constructor definition.

   Usage example:

       TODO"""
shared ConstructorDefinition constructorDefinition(
    name,
    parameters = Parameters(),
    block = [],
    extendedType = null,
    annotations = Annotations()) {

    IdentifierIsh name;
    Parameters|{Parameter*} parameters;
    {Declaration|Statement*} block;
    ExtendedType? extendedType;
    Annotations annotations;

    return ConstructorDefinition {
        name = lidentifier(name);
        block = package.block(block);
        parameters = parameters_internal(parameters);
        extendedType = extendedType;
        annotations = annotations;
    };
}

import ceylon.ast.core {
    Annotations,
    ConstructorDefinition,
    Declaration,
    ExtendedType,
    Parameter,
    Parameters,
    Statement
}

"""Creates a constructor definition.

   Usage example:

       constructorDefinition {
           name = "rgb";
           parameters = {
               ValueParameter {
                   type = baseType("Integer");
                   name = lidentifier("rgb");
               }
           };
           annotations = annotations {
               "Constructs a color, taking the red, green, and blue values
                from the argument integer.";
               "shared"
           };

           ValueSpecification {
               qualifier = This();
               name = lidentifier("rgb");
               specifier = Specifier(baseExpression("rgb"));
           }
       }"""
shared ConstructorDefinition constructorDefinition(
    name,
    parameters = Parameters(),
    block = [],
    extendedType = null,
    annotations = Annotations()) {

    IdentifierIsh name;
    Parameters|{Parameter*} parameters;
    {Declaration|Statement*} block;
    ExtendedType? extendedType;
    Annotations annotations;

    return ConstructorDefinition {
        name = lidentifier(name);
        block = package.block(block);
        parameters = parameters_internal(parameters);
        extendedType = extendedType;
        annotations = annotations;
    };
}

Add missing usage example for constructorDefinition

I must’ve forgotten this in 486bb73 (cc #71).


"Date and Time library for Ceylon language SDK.

 This library is loosely modeled/inspired by the JodaTime/JSR-310 date/time library.
 "
by ("Diego Coronel", "Roland Tepp")
module ceylon.time "1.2.3" {
    import ceylon.collection "1.2.3";
}

"Date and Time library for Ceylon language SDK.

 This library is loosely modeled/inspired by the JodaTime/JSR-310 date/time library.
 "
by ("Diego Coronel", "Roland Tepp")
module ceylon.time "1.2.3" {
}

Remove unused dependency on ceylon.collection


native("jvm") module org.otherone.vhostproxy.vertx "4" {
    shared import io.vertx.ceylon.core "3.3.2";
    //shared import "io.vertx:vertx-lang-ceylon" "3.3.0-SNAPSHOT";
    //shared import "io.vertx.lang.ceylon" "3.3.0-SNAPSHOT";
    import ceylon.regex "1.2.2";
    import ceylon.logging "1.2.2";
    //import ceylon.time "1.2.1";
    import java.base "7";
    //import "it.zero11:acme-client" "0.1.2";
    import ceylon.file "1.2.2";
    import ceylon.buffer "1.2.2";
}

native("jvm") module org.otherone.vhostproxy.vertx "4" {
    shared import io.vertx.ceylon.core "3.3.3";
    //shared import "io.vertx:vertx-lang-ceylon" "3.3.0-SNAPSHOT";
    //shared import "io.vertx.lang.ceylon" "3.3.0-SNAPSHOT";
    import ceylon.regex "1.3.1";
    import ceylon.logging "1.3.1";
    //import ceylon.time "1.2.1";
    import java.base "7";
    //import "it.zero11:acme-client" "0.1.2";
    import ceylon.file "1.3.1";
    import ceylon.buffer "1.3.1";
}

Update to ceylon 1.3.1 + vertx 3.3.3

Update to ceylon 1.3.1 + vertx 3.3.3


import ceylon.collection {
    MutableList,
    ArrayList
}
"Run the module `source_gen.ceylon.ast`.

 See [this gist](https://gist.github.com/lucaswerkmeister/a4da0fa5d9d5b14cc3e9)."
shared void run() {
    if (exists first = process.arguments.first, first == "--help") {
        print("https://gist.github.com/lucaswerkmeister/a4da0fa5d9d5b14cc3e9");
        return;
    }
    assert (exists type = process.arguments[0], exists superType = process.arguments[1]);
    variable Integer i = 2;
    MutableList<String->String> params = ArrayList<String->String>();
    while (i < process.arguments.size) {
        assert (exists paramType = process.arguments[i++]);
        assert (exists paramName = process.arguments[i++]);
        params.add(paramType->paramName);
    }
    variable String? line = process.readLine();
    StringBuilder doc = StringBuilder();
    while (exists l = line) {
        doc.append(l);
        line = process.readLine();
    }
    Generator(type, superType, params.sequence(), doc.string).run();
}

import ceylon.collection {
    MutableList,
    ArrayList
}
"Run the module `source_gen.ceylon.ast`.

 See [this gist](https://gist.github.com/lucaswerkmeister/a4da0fa5d9d5b14cc3e9)."
shared void run() {
    if (exists first = process.arguments.first, first == "--help") {
        print("https://gist.github.com/lucaswerkmeister/a4da0fa5d9d5b14cc3e9");
        return;
    }
    assert (exists type = process.arguments[0], exists superType = process.arguments[1]);
    variable Integer i = 2;
    MutableList<String->String> params = ArrayList<String->String>();
    while (i < process.arguments.size) {
        assert (exists paramType = process.arguments[i++]);
        assert (exists paramName = process.arguments[i++]);
        params.add(paramType->paramName);
    }
    variable String? line = process.readLine();
    StringBuilder doc = StringBuilder();
    while (exists l = line) {
        doc.append(l);
        doc.appendNewline();
        line = process.readLine();
    }
    Generator(type, superType, params.sequence(), doc.string).run();
}

Fix source-gen bug: doc would be missing line breaks


doc "Components for JDBC-based database connectivity."
by "Enrique Zamudio"
license "Apache Software License 2.0"
module ceylon.dbc '0.1' {
    import ceylon.math '0.3.2';
}

doc "This module offers some components for JDBC-based
     database connectivity. The main component is simply
     called Sql and is meant to be used with a `DataSource`
     that has been already been configured. "
by "Enrique Zamudio"
license "Apache Software License 2.0"
module ceylon.dbc '0.1' {
    import ceylon.math '0.3.3';
}

Update doc and ceylon.math version

Update doc and ceylon.math version


"A formatter for the Ceylon programming language."
by ("Lucas Werkmeister <mail@lucaswerkmeister.de>")
license("http://www.apache.org/licenses/LICENSE-2.0.html")
module ceylon.formatter "1.1.0" {
    shared import java.base "7";
    shared import com.redhat.ceylon.typechecker "1.1.0";
    shared import com.redhat.ceylon.common "1.1.0";
    shared import ceylon.file "1.1.0";
    import ceylon.interop.java "1.1.0";
    import ceylon.collection "1.1.0";
    optional import ceylon.test "1.1.0"; // for tests only, remove for release!
}

"A formatter for the Ceylon programming language."
by ("Lucas Werkmeister <mail@lucaswerkmeister.de>")
license ("http://www.apache.org/licenses/LICENSE-2.0.html")
module ceylon.formatter "1.1.0" {
    shared import java.base "7";
    shared import com.redhat.ceylon.typechecker "1.1.0";
    shared import com.redhat.ceylon.common "1.1.0";
    shared import ceylon.file "1.1.0";
    import ceylon.interop.java "1.1.0";
    import ceylon.collection "1.1.0";
    optional import ceylon.test "1.1.0"; // for tests only, remove for release!
}

Format source code (ws in license annotation)


"A formatter for the Ceylon programming language."
module ceylon.formatter "1.0.0" {
    shared import java.base "7";
    shared import com.redhat.ceylon.typechecker "1.0.0";
    shared import ceylon.file "1.0.0";
    import ceylon.time "1.0.0";
    import ceylon.interop.java "1.0.0";
    import ceylon.collection "1.0.0";
}

"A formatter for the Ceylon programming language."
module ceylon.formatter "1.0.0" {
    shared import java.base "7";
    shared import com.redhat.ceylon.typechecker "1.1.0";
    shared import ceylon.file "1.0.0";
    import ceylon.time "1.0.0";
    import ceylon.interop.java "1.0.0";
    import ceylon.collection "1.0.0";
}

Update for Ceylon 1.1 (typechecker version)


"Tests for the [[ceylon.ast module|module ceylon.ast]]"
by ("Lucas Werkmeister <mail@lucaswerkmeister.de>")
license("http://www.apache.org/licenses/LICENSE-2.0.html")
module test.ceylon.ast.api "1.1.0" {
    shared import ceylon.test "1.1.0";
    import ceylon.ast.api "1.1.0";
}

"Tests for the [[ceylon.ast.api module|module ceylon.ast.api]]"
by ("Lucas Werkmeister <mail@lucaswerkmeister.de>")
license("http://www.apache.org/licenses/LICENSE-2.0.html")
module test.ceylon.ast.api "1.1.0" {
    shared import ceylon.test "1.1.0";
    import ceylon.ast.api "1.1.0";
}

Fix ceylon.ast(.api) link in test.ceylon.ast.api doc

Aftermath of 408bc4a.


@test
shared void bug713() {
    value t = `Array<String>.OfSize` == `Array<String>.OfSize`;
}

@test
shared void bug713() {
    value t = `Array<String>.ofSize` == `Array<String>.ofSize`;
}

Fix a test for Array.ofSize

Fix a test for Array.ofSize


import ceylon.ast.core {
    Parameter,
    Parameters
}

"Converts a stream of [[parameters]] to a [[Parameters]] object."
Parameters parameters_internal(Parameters|{Parameter*} parameters) {
    if (is Parameters parameters) {
        return parameters;
    } else {
        assert (is {Parameter*} parameters);
        return Parameters(parameters.sequence());
    }
}

[Parameters+] parameterLists_internal({Parameters+}|Parameters|{Parameter*} parameters) {
    if (is Parameters parameters) {
        return [parameters];
    } else if (is {Parameters+} parameters) {
        assert (nonempty ret = parameters.sequence());
        return ret;
    } else {
        assert (is {Parameter*} parameters);
        return [parameters_internal(parameters)];
    }
}

Add create parameter lists internal function


import ceylon.ast.core {
    Annotations,
    Artifact,
    Module,
    ModuleImport,
    ModuleSpecifier,
    Repository,
    StringLiteral
}
import ceylon.ast.redhat {
    RedHatTransformer,
    moduleImportToCeylon,
    parseModuleImport
}
import com.redhat.ceylon.compiler.typechecker.tree {
    Tree {
        JImportModule=ImportModule
    }
}

shared object moduleImport satisfies ConcreteTest<ModuleImport,JImportModule> {

    String->ModuleImport construct(String->Module|ModuleSpecifier name, String->StringLiteral version, String->Annotations annotations = package.annotations.emptyAnnotations)
            => "``annotations.key`` import ``name.key`` ``version.key``;" -> ModuleImport(name.item, version.item, annotations.item);

    shared String->ModuleImport ceylonAstCore100ModuleImport = construct(fullPackageName.ceylonAstCorePackageName, stringLiteral._100VersionStringLiteral, annotations.sharedAnnotations);
    shared String->ModuleImport mavenCommonsCodecModuleImport = construct(moduleSpecifier.mavenCommonsCodecModuleSpecifier, stringLiteral._14VersionStringLiteral, annotations.emptyAnnotations);

    parse = parseModuleImport;
    fromCeylon = RedHatTransformer.transformModuleImport;
    toCeylon = moduleImportToCeylon;
    codes = [ceylonAstCore100ModuleImport, mavenCommonsCodecModuleImport];
}

import ceylon.ast.core {
    Annotations,
    Module,
    ModuleImport,
    ModuleSpecifier,
    StringLiteral
}
import ceylon.ast.redhat {
    RedHatTransformer,
    moduleImportToCeylon,
    parseModuleImport
}
import com.redhat.ceylon.compiler.typechecker.tree {
    Tree {
        JImportModule=ImportModule
    }
}

shared object moduleImport satisfies ConcreteTest<ModuleImport,JImportModule> {

    String->ModuleImport construct(String->Module|ModuleSpecifier name, String->StringLiteral version, String->Annotations annotations = package.annotations.emptyAnnotations)
            => "``annotations.key`` import ``name.key`` ``version.key``;" -> ModuleImport(name.item, version.item, annotations.item);

    shared String->ModuleImport ceylonAstCore100ModuleImport = construct(fullPackageName.ceylonAstCorePackageName, stringLiteral._100VersionStringLiteral, annotations.sharedAnnotations);
    shared String->ModuleImport mavenCommonsCodecModuleImport = construct(moduleSpecifier.mavenCommonsCodecModuleSpecifier, stringLiteral._14VersionStringLiteral, annotations.emptyAnnotations);

    parse = parseModuleImport;
    fromCeylon = RedHatTransformer.transformModuleImport;
    toCeylon = moduleImportToCeylon;
    codes = [ceylonAstCore100ModuleImport, mavenCommonsCodecModuleImport];
}

Remove unused imports in tests

Remove unused imports in tests


import ceylon.ast.core {
    thisInstance,
    ArgumentList,
    PositionalArguments,
    SpreadArgument
}
import ceylon.ast.create {
    createBaseExpression=baseExpression,
    createPositionalArguments=positionalArguments
}
import ceylon.test {
    test,
    assertEquals
}

test
shared void positionalArgumentsFunction() {
    assertEquals {
        actual = createPositionalArguments();
        expected = PositionalArguments(ArgumentList());
    };
    assertEquals {
        actual = createPositionalArguments(thisInstance, SpreadArgument(createBaseExpression("others")));
        expected = PositionalArguments(ArgumentList([thisInstance], SpreadArgument(createBaseExpression("others"))));
    };
}

import ceylon.ast.core {
    thisInstance,
    ArgumentList,
    PositionalArguments,
    SpreadArgument
}
import ceylon.ast.create {
    createBaseExpression=baseExpression,
    createPositionalArguments=positionalArguments
}
import ceylon.test {
    test,
    assertEquals
}

test
shared void positionalArguments() {
    assertEquals {
        actual = createPositionalArguments();
        expected = PositionalArguments(ArgumentList());
    };
    assertEquals {
        actual = createPositionalArguments(thisInstance, SpreadArgument(createBaseExpression("others")));
        expected = PositionalArguments(ArgumentList([thisInstance], SpreadArgument(createBaseExpression("others"))));
    };
}

Fix name of create positional arguments test


"The Ceylon language module containing the core definitions
 referred to by the [language specification][spec], along
 with some basic functionality of use to most programs:

 - The [[root package|package ceylon.language]] defines
   general-purpose functionality including support for
   [[numbers|Numeric]] and [[character strings|String]],
   [[streams|Iterable]] and [[sequences|Sequential]],
   [[exceptions|Throwable]], and [[null values|Null]].
 - The Ceylon _metamodel_ is defined in
   [[package ceylon.language.meta]] and its subpackages
   [[package ceylon.language.meta.model]] and
   [[package ceylon.language.meta.declaration]], which
   define interfaces for interacting with applied types and
   unapplied type declarations respectively.

 This module defines an abstraction over the basic
 facilities of the Java or JavaScript virtual machine,
 containing only functionality that can be easily
 implemented on both platforms. Thus, certain functionality,
 for example, concurrency, for which there is no common
 virtual machine-agnostic model, is not covered by the
 langauge module.

 The language module is an implicit dependency of every
 other Ceylon module, and may not be explicitly imported.

 [spec]: http://ceylon-lang.org/documentation/current/spec"
by ("Gavin King", "Tom Bentley", "Tako Schotanus",
   "Stephane Epardaud", "Enrique Zamudio")
license ("http://www.apache.org/licenses/LICENSE-2.0.html")
module ceylon.language "1.1.0" {}

"The Ceylon language module containing the core definitions
 referred to by the [language specification][spec], along
 with some basic functionality of use to most programs:

 - The [[root package|package ceylon.language]] defines
   general-purpose functionality including support for
   [[numbers|Numeric]] and [[character strings|String]],
   [[streams|Iterable]] and [[sequences|Sequential]],
   [[exceptions|Throwable]], and [[null values|Null]].
 - The Ceylon _metamodel_ is defined in
   [[package ceylon.language.meta]] and its subpackages
   [[package ceylon.language.meta.model]] and
   [[package ceylon.language.meta.declaration]], which
   define interfaces for interacting with applied types and
   unapplied type declarations respectively.

 This module defines an abstraction over the basic
 facilities of the Java or JavaScript virtual machine,
 containing only functionality that can be easily
 implemented on both platforms. Thus, certain functionality,
 for example, concurrency, for which there is no common
 virtual machine-agnostic model, is not covered by the
 language module.

 The language module is an implicit dependency of every
 other Ceylon module, and may not be explicitly imported.

 [spec]: http://ceylon-lang.org/documentation/current/spec"
by ("Gavin King", "Tom Bentley", "Tako Schotanus",
   "Stephane Epardaud", "Enrique Zamudio")
license ("http://www.apache.org/licenses/LICENSE-2.0.html")
module ceylon.language "1.1.0" {}

Fix doc typo: langauge -> language

Fix doc typo: langauge -> language


import ceylon.language.meta.declaration {
    AnnotatedDeclaration
}

"A key by which a [[Node]]’s additional information
 can be accessed."
shared class Key<Type>(name)
        given Type satisfies Object {
    "The name of this key. To avoid collisions
     with other keys, some use-site ID should be
     included, e. g. the name of the module that
     uses this key."
    see (`class ScopedKey`)
    String name;
    "A unique ID of this key, composed of
     the [[name]] argument and the [[Type]] type argument."
    shared String id = "`` `Type`.string ``:::``name``";
    string => id;
    shared actual Boolean equals(Object that) {
        if (is Key<Type> that) {
            return id == that.id;
        } else {
            return false;
        }
    }
    hash => id.hash;
}

"A [[Key]] with an explicitly provided scope, to avoid name collisions."
shared class ScopedKey<Type>(scope, name)
        extends Key<Type>("``scope.string``:::``name.string``")
        given Type satisfies Object {
    "The scope of this key, that is, the declaration
     of the program element that uses it.

     Most commonly the declaration of the enclosing
     class, package or module."
    AnnotatedDeclaration scope;
    "The name of this key.

     Unlike [[Key.name]], this name shouldn’t include some
     use-site ID, because that’s already provided by [[scope]]."
    String name;
}

import ceylon.language.meta.declaration {
    AnnotatedDeclaration
}

"A key by which a [[Node]]’s additional information
 can be accessed."
shared class Key<Type>(name)
        given Type satisfies Object {
    "The name of this key. To avoid collisions
     with other keys, some use-site ID should be
     included, e. g. the name of the module that
     uses this key."
    see (`class ScopedKey`)
    String name;
    "A unique ID of this key, composed of
     the [[name]] argument and the [[Type]] type argument."
    shared String id = "`` `Type`.string ``:::``name``";
    string => id;
    shared actual Boolean equals(Object that) {
        if (is Key<Type> that) {
            return id == that.id;
        } else {
            return false;
        }
    }
    hash => id.hash;
}

"A [[Key]] with an explicitly provided scope, to avoid name collisions.

 Usage example:

     shared Key<Token[]> tokensKey
             = ScopedKey<Token[]>(`class CeylonParser`, \"tokens\");"
shared class ScopedKey<Type>(scope, name)
        extends Key<Type>("``scope.string``:::``name.string``")
        given Type satisfies Object {
    "The scope of this key, that is, the declaration
     of the program element that uses it.

     Most commonly the declaration of the enclosing
     class, package or module."
    AnnotatedDeclaration scope;
    "The name of this key.

     Unlike [[Key.name]], this name shouldn’t include some
     use-site ID, because that’s already provided by [[scope]]."
    String name;
}

Add usage example to ScopedKey documentation


interface SecondOrder<Box>
        given Box<Value> {
    shared formal Box<Float> createBox(Float float);
}
void takesCallableParamWithTypeParam(T f<T>(T t)) {}

Add test for callable parameters with type parameters

This part of #108 actually already works, since parameters don’t have
their own node type: They’re AttributeDeclarations or
MethodDeclarations, and MethodDeclarations of course already support
type parameters.


import ceylon.io.impl {
    InputStreamAdapter,
    OutputStreamAdapter
}

import java.lang {
    System {
        javaIn=\iin,
        javaOut=\iout,
        javaErr=err
    }
}

"A [[ReadableFileDescriptor]] for the virtual machine's standard input"
ReadableFileDescriptor stdin = InputStreamAdapter(javaIn);

"A [[WritableFileDescriptor]] for the virtual machine's standard output stream."
WritableFileDescriptor stdout = OutputStreamAdapter(javaOut);

"A [[WritableFileDescriptor]] for the virtual machine's standard error stream."
WritableFileDescriptor stderr = OutputStreamAdapter(javaErr);

import ceylon.io.impl {
    InputStreamAdapter,
    OutputStreamAdapter
}

import java.lang {
    System {
        javaIn=\iin,
        javaOut=\iout,
        javaErr=err
    }
}

"A [[ReadableFileDescriptor]] for the virtual machine's standard input stream."
ReadableFileDescriptor stdin = InputStreamAdapter(javaIn);

"A [[WritableFileDescriptor]] for the virtual machine's standard output stream."
WritableFileDescriptor stdout = OutputStreamAdapter(javaOut);

"A [[WritableFileDescriptor]] for the virtual machine's standard error stream."
WritableFileDescriptor stderr = OutputStreamAdapter(javaErr);

Fix typo in doc text

Fix typo in doc text


import ceylon.ast.api {
    Type
}
import com.redhat.ceylon.compiler.typechecker.tree {
    Tree {
        JGroupedType=GroupedType,
        JSimpleType=SimpleType,
        JStaticType=StaticType
    }
}
import ceylon.ast.redhat {
    groupedTypeToCeylon,
    createParser,
    simpleTypeToCeylon
}

"Converts a RedHat AST [[StaticType|JStaticType]] to a `ceylon.ast` [[Type]]."
shared Type typeToCeylon(JStaticType type) {
    switch (type)
    case (is JSimpleType) { return simpleTypeToCeylon(type); }
    case (is JGroupedType) { return groupedTypeToCeylon(type); }
    else {
        throw Error("Not yet implemented!"); // TODO
    }
}

"Compiles the given [[code]] for a Type
 into a [[Type]] using the Ceylon compiler
 (more specifically, the rule for a `type`)."
shared Type? compileType(String code) {
    if (exists jType = createParser(code).type()) {
        return typeToCeylon(jType);
    } else {
        return null;
    }
}

import ceylon.ast.api {
    Type
}
import com.redhat.ceylon.compiler.typechecker.tree {
    Tree {
        JGroupedType=GroupedType,
        JIterableType=IterableType,
        JOptionalType=OptionalType,
        JSequenceType=SequenceType,
        JSimpleType=SimpleType,
        JStaticType=StaticType,
        JTupleType=TupleType
    }
}
import ceylon.ast.redhat {
    groupedTypeToCeylon,
    createParser,
    simpleTypeToCeylon
}

"Converts a RedHat AST [[StaticType|JStaticType]] to a `ceylon.ast` [[Type]]."
shared Type typeToCeylon(JStaticType type) {
    switch (type)
    case (is JSimpleType) { return simpleTypeToCeylon(type); }
    case (is JTupleType) { return tupleTypeToCeylon(type); }
    case (is JIterableType) { return iterableTypeToCeylon(type); }
    case (is JGroupedType) { return groupedTypeToCeylon(type); }
    case (is JOptionalType) { return optionalTypeToCeylon(type); }
    case (is JSequenceType) { return sequentialTypeToCeylon(type); }
    else {
        throw Error("Not yet implemented!"); // TODO
    }
}

"Compiles the given [[code]] for a Type
 into a [[Type]] using the Ceylon compiler
 (more specifically, the rule for a `type`)."
shared Type? compileType(String code) {
    if (exists jType = createParser(code).type()) {
        return typeToCeylon(jType);
    } else {
        return null;
    }
}

Add missing switch type cases to typeToCeylon


import ceylon.file { ... }

import java.nio.file { JPath=Path,
                       Files { movePath=move,
                               newDirectoryStream } }

class ConcreteDirectory(JPath jpath)
        extends ConcreteExistingResource(jpath)
        satisfies Directory {
    shared actual Iterable<Path> childPaths(String filter) {
        //TODO: efficient impl
        value sb = SequenceBuilder<Path>();
        value stream = newDirectoryStream(jpath, filter);
        value iter = stream.iterator();
        while (iter.hasNext()) {
            sb.append(ConcretePath(iter.next()));
        }
        stream.close();
        return sb.sequence;
    }
    shared actual Iterable<ExistingResource> children(String filter) {
        return elements { for (p in childPaths(filter))
                 if (is ExistingResource r=p.resource) r };
    }
    shared actual Iterable<File> files(String filter) {
        return elements { for (p in childPaths(filter))
                 if (is File r=p.resource) r };
    }
    shared actual Iterable<Directory> childDirectories(String filter) {
        return elements { for (p in childPaths(filter))
                 if (is Directory r=p.resource) r };
    }
    shared actual Resource childResource(Path|String subpath) {
        return path.childPath(subpath).resource;
    }
    shared actual Directory move(Nil target) {
        return ConcreteDirectory( movePath(jpath, asJPath(target.path)) );
    }
}

import ceylon.file { ... }

import java.nio.file { JPath=Path,
                       Files { movePath=move,
                               newDirectoryStream } }

class ConcreteDirectory(JPath jpath)
        extends ConcreteExistingResource(jpath)
        satisfies Directory {
    shared actual Iterable<Path> childPaths(String filter) {
        //TODO: efficient impl
        value sb = SequenceBuilder<Path>();
        value stream = newDirectoryStream(jpath, filter);
        value iter = stream.iterator();
        while (iter.hasNext()) {
            sb.append(ConcretePath(iter.next()));
        }
        stream.close();
        return sb.sequence;
    }
    shared actual Iterable<ExistingResource> children(String filter) {
        return elements { {for (p in childPaths(filter))
                 if (is ExistingResource r=p.resource) r}... };
    }
    shared actual Iterable<File> files(String filter) {
        return elements { {for (p in childPaths(filter))
                 if (is File r=p.resource) r}... };
    }
    shared actual Iterable<Directory> childDirectories(String filter) {
        return elements { {for (p in childPaths(filter))
                 if (is Directory r=p.resource) r}... };
    }
    shared actual Resource childResource(Path|String subpath) {
        return path.childPath(subpath).resource;
    }
    shared actual Directory move(Nil target) {
        return ConcreteDirectory( movePath(jpath, asJPath(target.path)) );
    }
}

Fix for sequenced args and iterables

Fix for sequenced args and iterables


import ceylon.test { test }
import ceylon.formatter { FormattingWriter, maxDesire }
import ceylon.formatter.options { parseLineBreakStrategy, FormattingOptions, LineBreakStrategy }
import ceylon.file { Writer }

test
shared void testDumbLineBreaks() {
    object writer satisfies Writer {
        shared actual void destroy() {}
        shared actual void flush() {}
        shared actual void write(String string) {}
        shared actual void writeLine(String line) {}
    }
    FormattingWriter w = FormattingWriter(null, writer, FormattingOptions());

    LineBreakStrategy? dumbLineBreaks = parseLineBreakStrategy("dumb");
    assert (exists dumbLineBreaks);

    assert(exists location1 = dumbLineBreaks.lineBreakLocation([
        w.Token("breakHere", false, 1, maxDesire, maxDesire),
        *{
            for (i in 1..10)
                w.Token("noBreakHere``i``", true, null, maxDesire, maxDesire)
        }], 0, 20), location1 == 1);

    assert(is Null n = dumbLineBreaks.lineBreakLocation([
        for (i in 1..10)
            w.Token("noBreakHere``i``", false, null, maxDesire, maxDesire)
        ], 0, 20));

    SequenceBuilder<FormattingWriter.QueueElement> s = SequenceBuilder<FormattingWriter.QueueElement>();
    for (i in 1..10) {
        s.append(w.Token("noBreakHere``i``", false, null, maxDesire, maxDesire));
    }
    s.append(w.LineBreak());
    assert(exists location2 = dumbLineBreaks.lineBreakLocation(s.sequence, 0, 20), location2 == 10);
}

Add a test for DumbLineBreaks

Add a test for DumbLineBreaks