Quellcodebibliothek Statistik Leitseite products/sources/formale Sprachen/C/Firefox/js/src/tests/non262/reflect-parse/   (Browser von der Mozilla Stiftung Version 136.0.1©)  Datei vom 10.2.2025 mit Größe 25 kB image not shown  

Quelle  classes.js   Sprache: JAVA

 
// |reftest| slow skip-if(!xulRuntime.shell)
// Classes
function testClasses() {
    function methodFun(id, kind, generator, args, body = []) {
        assertEq(generator && kind === "method", generator);
        assertEq(typeof id === 'string' || id === nulltrue);
        let methodName;
        switch (kind) {
            case "method":
                methodName = typeof id === 'string' ? ident(id) : null;
                break;
            case "get":
            case "set":
                methodName = ident(`${kind} ${typeof id === 'string' ? id : ""}`);
                break;
            default:
                methodName = null;
                break;
        }
        return generator
            ? genFunExpr("es6", methodName, args.map(ident), blockStmt(body))
            : funExpr(methodName, args.map(ident), blockStmt(body));
    }

    function simpleMethod(id, kind, generator, args = [], isStatic = false) {
        return classMethod(ident(id),
            methodFun(id, kind, generator, args),
            kind, isStatic);
    }
    function ctorWithName(id, body = []) {
        return classMethod(ident("constructor"),
            methodFun(id, "method"false, [], body),
            "method"false);
    }
    function emptyCPNMethod(id, isStatic) {
        return classMethod(computedName(lit(id)),
            funExpr(null, [], blockStmt([])),
            "method", isStatic);
    }

    function assertClassExpr(str, methods, heritage = null, name = null) {
        let template = classExpr(name, heritage, methods);
        assertExpr("(" + str + ")", template);
    }

    // FunctionExpression of constructor has class name as its id.
    // FIXME: Implement ES6 function "name" property semantics (bug 883377).
    let ctorPlaceholder = {};
    function assertClass(str, methods, heritage = null, constructorBody = []) {
        let namelessStr = str.replace("NAME""");
        let namedStr = str.replace("NAME""Foo");
        let namedCtor = ctorWithName("Foo", constructorBody);
        let namelessCtor = ctorWithName(null, constructorBody);
        let namelessMethods = methods.map(x => x == ctorPlaceholder ? namelessCtor : x);
        let namedMethods = methods.map(x => x == ctorPlaceholder ? namedCtor : x);
        assertClassExpr(namelessStr, namelessMethods, heritage);
        assertClassExpr(namedStr, namedMethods, heritage, ident("Foo"));

        let template = classStmt(ident("Foo"), heritage, namedMethods);
        assertStmt(namedStr, template);
    }
    function assertNamedClassError(str, error) {
        assertError(str, error);
        assertError("(" + str + ")", error);
    }
    function assertClassError(str, error) {
        assertNamedClassError(str, error);
        assertError("(" + str.replace("NAME""") + ")", error);
    }

    /* Trivial classes */
    // Unnamed class statements are forbidden, but unnamed class expressions are
    // just fine.
    assertError("class { constructor() { } }", SyntaxError);
    assertClass("class NAME { constructor() { } }", [ctorPlaceholder]);

    // A class name must actually be a name
    assertNamedClassError("class x.y { constructor() {} }", SyntaxError);
    assertNamedClassError("class [] { constructor() {} }", SyntaxError);
    assertNamedClassError("class {x} { constructor() {} }", SyntaxError);
    assertNamedClassError("class for { constructor() {} }", SyntaxError);

    // Allow methods and accessors
    assertClass("class NAME { constructor() { } method() { } }",
        [ctorPlaceholder, simpleMethod("method""method"false)]);

    assertClass("class NAME { constructor() { } get method() { } }",
        [ctorPlaceholder, simpleMethod("method""get"false)]);

    assertClass("class NAME { constructor() { } set method(x) { } }",
        [ctorPlaceholder, simpleMethod("method""set"false, ["x"])]);

    /* Static */
    assertClass(`class NAME {
                   constructor() { };
                   static method() { };
                   static *methodGen() { };
                   static get getter() { };
                   static set setter(x) { }
                 }`,
        [ctorPlaceholder,
            simpleMethod("method""method"false, [], true),
            simpleMethod("methodGen""method"true, [], true),
            simpleMethod("getter""get"false, [], true),
            simpleMethod("setter""set"false, ["x"], true)]);

    // It's not an error to have a method named static, static, or not.
    assertClass("class NAME { constructor() { } static() { } }",
        [ctorPlaceholder, simpleMethod("static""method"false)]);
    assertClass("class NAME { static static() { }; constructor() { } }",
        [simpleMethod("static""method"false, [], true), ctorPlaceholder]);
    assertClass("class NAME { static get static() { }; constructor() { } }",
        [simpleMethod("static""get"false, [], true), ctorPlaceholder]);
    assertClass("class NAME { constructor() { }; static set static(x) { } }",
        [ctorPlaceholder, simpleMethod("static""set"false, ["x"], true)]);

    // You do, however, have to put static in the right spot
    assertClassError("class NAME { constructor() { }; get static foo() { } }", SyntaxError);

    // Spec disallows "prototype" as a static member in a class, since that
    // one's important to make the desugaring work
    assertClassError("class NAME { constructor() { } static prototype() { } }", SyntaxError);
    assertClassError("class NAME { constructor() { } static *prototype() { } }", SyntaxError);
    assertClassError("class NAME { static get prototype() { }; constructor() { } }"SyntaxError);
    assertClassError("class NAME { static set prototype(x) { }; constructor() { } }", SyntaxError);

    // You are, however, allowed to have a CPN called prototype as a static
    assertClass("class NAME { constructor() { }; static [\"prototype\"]() { } }",
        [ctorPlaceholder, emptyCPNMethod("prototype"true)]);

    /* Constructor */
    // Allow default constructors
    assertClass("class NAME { }", []);
    assertClass("class NAME extends null { }", [], lit(null));

    // Derived class constructor must have curly brackets
    assertClassError("class NAME extends null { constructor() 1 }", SyntaxError);

    // It is an error to have two methods named constructor, but not other
    // names, regardless if one is an accessor or a generator or static.
    assertClassError("class NAME { constructor() { } constructor(a) { } }", SyntaxError);
    let methods = [["method() { }", simpleMethod("method""method"false)],
    ["*method() { }", simpleMethod("method""method"true)],
    ["get method() { }", simpleMethod("method""get"false)],
    ["set method(x) { }", simpleMethod("method""set"false, ["x"])],
    ["static method() { }", simpleMethod("method""method"false, [], true)],
    ["static *method() { }", simpleMethod("method""method"true, [], true)],
    ["static get method() { }", simpleMethod("method""get"false, [], true)],
    ["static set method(x) { }", simpleMethod("method""set"false, ["x"], true)]];
    let i, j;
    for (i = 0; i < methods.length; i++) {
        for (j = 0; j < methods.length; j++) {
            let str = "class NAME { constructor() { } " +
                methods[i][0] + " " + methods[j][0] +
                " }";
            assertClass(str, [ctorPlaceholder, methods[i][1], methods[j][1]]);
        }
    }

    // It is, however, not an error to have a constructor, and a method with a
    // computed property name 'constructor'
    assertClass("class NAME { constructor () { } [\"constructor\"] () { } }",
        [ctorPlaceholder, emptyCPNMethod("constructor"false)]);

    // It is an error to have a generator or accessor named constructor
    assertClassError("class NAME { *constructor() { } }", SyntaxError);
    assertClassError("class NAME { get constructor() { } }", SyntaxError);
    assertClassError("class NAME { set constructor() { } }", SyntaxError);

    /* Semicolons */
    // Allow Semicolons in Class Definitions
    assertClass("class NAME { constructor() { }; }", [ctorPlaceholder]);

    // Allow more than one semicolon, even in otherwise trivial classses
    assertClass("class NAME { ;;; constructor() { } }", [ctorPlaceholder]);

    // Semicolons are optional, even if the methods share a line
    assertClass("class NAME { method() { } constructor() { } }",
        [simpleMethod("method""method"false), ctorPlaceholder]);

    /* Generators */
    // No yield as a class name inside a generator
    assertError(`function *foo() {
                    class yield {
                        constructor() { }
                    }
                 }`, SyntaxError);
    assertError(`function *foo() {
                    (class yield {
                        constructor() { }
                    })
                 }`, SyntaxError);

    // No legacy generators for methods.
    assertClassError(`class NAME {
                          constructor() { yield 2; }
                      }`, SyntaxError);
    assertClassError(`class NAME {
                          method() { yield 2; }
                      }`, SyntaxError);
    assertClassError(`class NAME {
                          get method() { yield 2; }
                      }`, SyntaxError);
    assertClassError(`class NAME {
                          set method() { yield 2; }
                      }`, SyntaxError);

    // Methods may be generators, but not accessors
    assertClassError("class NAME { constructor() { } *get foo() { } }", SyntaxError);
    assertClassError("class NAME { constructor() { } *set foo() { } }", SyntaxError);

    assertClass("class NAME { *method() { } constructor() { } }",
        [simpleMethod("method""method"true), ctorPlaceholder]);

    /* Strictness */
    // yield is a strict-mode keyword, and class definitions are always strict.
    assertClassError("class NAME { constructor() { var yield; } }", SyntaxError);

    // Beware of the strictness of computed property names. Here use bareword
    // deletion (a deprecated action) to check.
    assertClassError("class NAME { constructor() { } [delete bar]() { }}", SyntaxError);

    /* Bindings */
    // Class statements bind lexically, so they should collide with other
    // in-block lexical bindings, but class expressions don't.
    let FooCtor = ctorWithName("Foo");
    assertError("{ let Foo; class Foo { constructor() { } } }", SyntaxError);
    assertStmt("{ let Foo; (class Foo { constructor() { } }) }",
        blockStmt([letDecl([{ id: ident("Foo"), init: null }]),
        exprStmt(classExpr(ident("Foo"), null, [FooCtor]))]));
    assertError("{ const Foo = 0; class Foo { constructor() { } } }", SyntaxError);
    assertStmt("{ const Foo = 0; (class Foo { constructor() { } }) }",
        blockStmt([constDecl([{ id: ident("Foo"), init: lit(0) }]),
        exprStmt(classExpr(ident("Foo"), null, [FooCtor]))]));
    assertError("{ class Foo { constructor() { } } class Foo { constructor() { } } }", SyntaxError);
    assertStmt(`{
                    (class Foo {
                        constructor() { }
                     },
                     class Foo {
                        constructor() { }
                     });
                }`,
        blockStmt([exprStmt(seqExpr([classExpr(ident("Foo"), null, [FooCtor]),
        classExpr(ident("Foo"), null, [FooCtor])]))]));
    assertStmt(`{
                    var x = class Foo { constructor() { } };
                    class Foo { constructor() { } }
                }`,
        blockStmt([varDecl([{
            id: ident("x"),
            init: classExpr(ident("Foo"), null, [FooCtor])
        }]),
        classStmt(ident("Foo"), null, [FooCtor])]));


    // Can't make a lexical binding without a block.
    assertError("if (1) class Foo { constructor() { } }", SyntaxError);

    /* Heritage Expressions */
    // It's illegal to have things that look like "multiple inheritance":
    // non-parenthesized comma expressions.
    assertClassError("class NAME extends null, undefined { constructor() { } }", SyntaxError);

    // Again check for strict-mode in heritage expressions
    assertClassError("class NAME extends (delete x) { constructor() { } }", SyntaxError);

    // You must specify an inheritance if you say "extends"
    assertClassError("class NAME extends { constructor() { } }", SyntaxError);

    // "extends" is still a valid name for a method
    assertClass("class NAME { constructor() { }; extends() { } }",
        [ctorPlaceholder, simpleMethod("extends""method"false)]);

    // Immediate expression
    assertClass("class NAME extends null { constructor() { } }",
        [ctorPlaceholder], lit(null));

    // Sequence expresson
    assertClass("class NAME extends (undefined, undefined) { constructor() { } }",
        [ctorPlaceholder], seqExpr([ident("undefined"), ident("undefined")]));

    // Function expression
    let emptyFunction = funExpr(null, [], blockStmt([]));
    assertClass("class NAME extends function(){ } { constructor() { } }",
        [ctorPlaceholder], emptyFunction);

    // New expression
    assertClass("class NAME extends new function(){ }() { constructor() { } }",
        [ctorPlaceholder], newExpr(emptyFunction, []));

    // Call expression
    assertClass("class NAME extends function(){ }() { constructor() { } }",
        [ctorPlaceholder], callExpr(emptyFunction, []));

    // Dot expression
    assertClass("class NAME extends {}.foo { constructor() { } }",
        [ctorPlaceholder], dotExpr(objExpr([]), ident("foo")));

    // Member expression
    assertClass("class NAME extends {}[foo] { constructor() { } }",
        [ctorPlaceholder], memExpr(objExpr([]), ident("foo")));

    // #constructor is an invalid private method name.
    assertClassError("class NAME { #constructor() { } }", SyntaxError);

    const method = ["#method() { }", simpleMethod("#method""method"false)];
    const generator = ["*#method() { }", simpleMethod("#method""method"true)];
    const getter = ["get #method() { }", simpleMethod("#method""get"false)];
    const setter = ["set #method(x) { }", simpleMethod("#method""set"false, ["x"])];
    for (const [source, parsed] of [method, generator, getter, setter]) {
        assertClass(`class NAME { constructor() { } ${source} }`, [ctorPlaceholder, parsed]);
    }

    // Private getters and setters of the same name are allowed.
    assertClass(`class NAME { constructor() { } ${getter[0]} ${setter[0]} }`,
        [ctorPlaceholder, getter[1], setter[1]]);
    assertClass(`class NAME { constructor() { } ${setter[0]} ${getter[0]} }`,
        [ctorPlaceholder, setter[1], getter[1]]);

    // Private method names can't be used multiple times, other than for a getter/setter pair.
    for (const [source1, _] of [method, generator, getter, setter]) {
        for (const [source2, _] of [method, generator]) {
            assertClassError(`class NAME { constructor() { } ${source1} ${source2} }`, SyntaxError);
        }
    }

    assertClassError(`class NAME { constructor() { } ${setter[0]} ${setter[0]} }`, SyntaxError);
    assertClassError(`class NAME { constructor() { } ${getter[0]} ${getter[0]} }`, SyntaxError);


    /* SuperProperty */
    // NOTE: Some of these tests involve object literals, as SuperProperty is a
    // valid production in any method definition, including in objectl
    // litterals. These tests still fall here, as |super| is not implemented in
    // any form without classes.

    function assertValidSuperProps(assertion, makeStr, makeExpr, type, generator, args, static,
        extending) {
        let superProperty = superProp(ident("prop"));
        let superMember = superElem(lit("prop"));

        let situations = [
            ["super.prop", superProperty],
            ["super['prop']", superMember],
            ["super.prop()", callExpr(superProperty, [])],
            ["super['prop']()", callExpr(superMember, [])],
            ["new super.prop()", newExpr(superProperty, [])],
            ["new super['prop']()", newExpr(superMember, [])],
            ["delete super.prop", unExpr("delete", superProperty)],
            ["delete super['prop']", unExpr("delete", superMember)],
            ["++super.prop", updExpr("++", superProperty, true)],
            ["super['prop']--", updExpr("--", superMember, false)],
            ["super.prop = 4", aExpr("=", superProperty, lit(4))],
            ["super['prop'] = 4", aExpr("=", superMember, lit(4))],
            ["super.prop += 4", aExpr("+=", superProperty, lit(4))],
            ["super['prop'] += 4", aExpr("+=", superMember, lit(4))],
            ["super.prop -= 4", aExpr("-=", superProperty, lit(4))],
            ["super['prop'] -= 4", aExpr("-=", superMember, lit(4))],
            ["super.prop *= 4", aExpr("*=", superProperty, lit(4))],
            ["super['prop'] *= 4", aExpr("*=", superMember, lit(4))],
            ["super.prop /= 4", aExpr("/=", superProperty, lit(4))],
            ["super['prop'] /= 4", aExpr("/=", superMember, lit(4))],
            ["super.prop %= 4", aExpr("%=", superProperty, lit(4))],
            ["super['prop'] %= 4", aExpr("%=", superMember, lit(4))],
            ["super.prop <<= 4", aExpr("<<=", superProperty, lit(4))],
            ["super['prop'] <<= 4", aExpr("<<=", superMember, lit(4))],
            ["super.prop >>= 4", aExpr(">>=", superProperty, lit(4))],
            ["super['prop'] >>= 4", aExpr(">>=", superMember, lit(4))],
            ["super.prop >>>= 4", aExpr(">>>=", superProperty, lit(4))],
            ["super['prop'] >>>= 4", aExpr(">>>=", superMember, lit(4))],
            ["super.prop |= 4", aExpr("|=", superProperty, lit(4))],
            ["super['prop'] |= 4", aExpr("|=", superMember, lit(4))],
            ["super.prop ^= 4", aExpr("^=", superProperty, lit(4))],
            ["super['prop'] ^= 4", aExpr("^=", superMember, lit(4))],
            ["super.prop &= 4", aExpr("&=", superProperty, lit(4))],
            ["super['prop'] &= 4", aExpr("&=", superMember, lit(4))],

            // We can also use super from inside arrow functions in method
            // definitions
            ["()=>super.prop", arrowExpr([], superProperty)],
            ["()=>super['prop']", arrowExpr([], superMember)]];

        for (let situation of situations) {
            let sitStr = situation[0];
            let sitExpr = situation[1];

            let fun = methodFun("method", type, generator, args, [exprStmt(sitExpr)]);
            let str = makeStr(sitStr, type, generator, args, static, extending);
            assertion(str, makeExpr(fun, type, static), extending);
        }
    }

    function assertValidSuperPropTypes(assertion, makeStr, makeExpr, static, extending) {
        for (let type of ["method""get""set"]) {
            if (type === "method") {
                // methods can also be generators
                assertValidSuperProps(assertion, makeStr, makeExpr, type, true, [], static, extending);
                assertValidSuperProps(assertion, makeStr, makeExpr, type, false, [], static, extending);
                continue;
            }

            // Setters require 1 argument, and getters require 0
            assertValidSuperProps(assertion, makeStr, makeExpr, type, false,
                type === "set" ? ["x"] : [], static, extending);
        }
    }

    function makeSuperPropMethodStr(propStr, type, generator, args) {
        return `${type === "method" ? "" : type} ${generator ? "*" : ""} method(${args.join(",")})
                {
                    ${propStr};
                }`;
    }

    function makeClassSuperPropStr(propStr, type, generator, args, static, extending) {
        return `class NAME ${extending ? "extends null" : ""} {
                    constructor() { };
                    ${static ? "static" : ""} ${makeSuperPropMethodStr(propStr, type, generator, args)}
                }`;
    }
    function makeClassSuperPropExpr(fun, type, static) {
        // We are going right into assertClass, so we don't have to build the
        // entire statement.
        return [ctorPlaceholder,
            classMethod(ident("method"), fun, type, static)];
    }
    function doClassSuperPropAssert(str, expr, extending) {
        assertClass(str, expr, extending ? lit(null) : null);
    }
    function assertValidClassSuperPropExtends(extending) {
        // super.prop and super[prop] are valid, regardless of whether the
        // method is static or not
        assertValidSuperPropTypes(doClassSuperPropAssert, makeClassSuperPropStr, makeClassSuperPropExpr,
            false, extending);
        assertValidSuperPropTypes(doClassSuperPropAssert, makeClassSuperPropStr, makeClassSuperPropExpr,
            true, extending);
    }
    function assertValidClassSuperProps() {
        // super.prop and super[prop] are valid, regardless of class heritage
        assertValidClassSuperPropExtends(false);
        assertValidClassSuperPropExtends(true);
    }

    function makeOLSuperPropStr(propStr, type, generator, args) {
        let str = `({ ${makeSuperPropMethodStr(propStr, type, generator, args)} })`;
        return str;
    }
    function makeOLSuperPropExpr(fun) {
        return objExpr([{ type: "Property", key: ident("method"), value: fun }]);
    }
    function assertValidOLSuperProps() {
        assertValidSuperPropTypes(assertExpr, makeOLSuperPropStr, makeOLSuperPropExpr);
    }


    // Check all valid uses of SuperProperty
    assertValidClassSuperProps();
    assertValidOLSuperProps();

    // SuperProperty is forbidden outside of method definitions.
    assertError("function foo () { super.prop; }", SyntaxError);
    assertError("(function () { super.prop; }", SyntaxError);
    assertError("(()=>super.prop)", SyntaxError);
    assertError("function *foo() { super.prop; }", SyntaxError);
    assertError("super.prop", SyntaxError);
    assertError("function foo () { super['prop']; }", SyntaxError);
    assertError("(function () { super['prop']; }", SyntaxError);
    assertError("(()=>super['prop'])", SyntaxError);
    assertError("function *foo() { super['prop']; }", SyntaxError);
    assertError("super['prop']", SyntaxError);

    // Or inside functions inside method definitions...
    assertClassError("class NAME { constructor() { function nested() { super.prop; }}}", SyntaxError);

    // Bare super is forbidden
    assertError("super", SyntaxError);

    // Even where super is otherwise allowed
    assertError("{ foo() { super } }", SyntaxError);
    assertClassError("class NAME { constructor() { super; } }", SyntaxError);

    /* SuperCall */

    // SuperCall is invalid outside derived class constructors.
    assertError("super()", SyntaxError);
    assertError("(function() { super(); })", SyntaxError);


    // Even in class constructors
    assertClassError("class NAME { constructor() { super(); } }", SyntaxError);

    function superConstructor(args) {
        return classMethod(ident("constructor"),
            methodFun("NAME""method"false,
                [], [exprStmt(superCallExpr(args))]),
            "method"false);
    }

    function superCallBody(args) {
        return [exprStmt(superCallExpr(args))];
    }

    // SuperCall works with various argument configurations.
    assertClass("class NAME extends null { constructor() { super() } }",
        [ctorPlaceholder], lit(null), superCallBody([]));
    assertClass("class NAME extends null { constructor() { super(1) } }",
        [ctorPlaceholder], lit(null), superCallBody([lit(1)]));
    assertClass("class NAME extends null { constructor() { super(1, a) } }",
        [ctorPlaceholder], lit(null), superCallBody([lit(1), ident("a")]));
    assertClass("class NAME extends null { constructor() { super(...[]) } }",
        [ctorPlaceholder], lit(null), superCallBody([spread(arrExpr([]))]));

    /* EOF */
    // Clipped classes should throw a syntax error
    assertClassError("class NAME {", SyntaxError);
    assertClassError("class NAME {;", SyntaxError);
    assertClassError("class NAME { constructor", SyntaxError);
    assertClassError("class NAME { constructor(", SyntaxError);
    assertClassError("class NAME { constructor()", SyntaxError);
    assertClassError("class NAME { constructor()", SyntaxError);
    assertClassError("class NAME { constructor() {", SyntaxError);
    assertClassError("class NAME { constructor() { }", SyntaxError);
    assertClassError("class NAME { static", SyntaxError);
    assertClassError("class NAME { static y", SyntaxError);
    assertClassError("class NAME { static *", SyntaxError);
    assertClassError("class NAME { static *y", SyntaxError);
    assertClassError("class NAME { static get", SyntaxError);
    assertClassError("class NAME { static get y", SyntaxError);
    assertClassError("class NAME { static ;", SyntaxError);
    assertClassError("class NAME extends", SyntaxError);
    assertClassError("class NAME { constructor() { super", SyntaxError);
    assertClassError("class NAME { constructor() { super.", SyntaxError);
    assertClassError("class NAME { constructor() { super.x", SyntaxError);
    assertClassError("class NAME { constructor() { super.m(", SyntaxError);
    assertClassError("class NAME { constructor() { super[", SyntaxError);
    assertClassError("class NAME { constructor() { super(", SyntaxError);

    // Can not omit curly brackets
    assertClassError("class NAME { constructor() ({}) }", SyntaxError);
    assertClassError("class NAME { constructor() void 0 }", SyntaxError);
    assertClassError("class NAME { constructor() 1 }", SyntaxError);
    assertClassError("class NAME { constructor() false }", SyntaxError);
    assertClassError("class NAME { constructor() {} a() ({}) }", SyntaxError);
    assertClassError("class NAME { constructor() {} a() void 0 }", SyntaxError);
    assertClassError("class NAME { constructor() {} a() 1 }", SyntaxError);
    assertClassError("class NAME { constructor() {} a() false }", SyntaxError);

}

runtest(testClasses);

Messung V0.5
C=88 H=91 G=89

¤ Dauer der Verarbeitung: 0.17 Sekunden  (vorverarbeitet)  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.