TableBuilder.avt

Переключить прокрутку окна
Загрузить этот исходный код

/*
    Компилятор языка программирования
    Объектно-ориентированный продвинутый векторный транслятор

    Copyright © 2021, 2024 Малик Разработчик

    Это свободная программа: вы можете перераспространять ее и/или изменять
    ее на условиях Стандартной общественной лицензии GNU в том виде,
    в каком она была опубликована Фондом свободного программного обеспечения;
    либо версии 3 лицензии, либо (по вашему выбору) любой более поздней версии.

    Эта программа распространяется в надежде, что она будет полезной,
    но БЕЗО ВСЯКИХ ГАРАНТИЙ; даже без неявной гарантии ТОВАРНОГО ВИДА
    или ПРИГОДНОСТИ ДЛЯ ОПРЕДЕЛЕННЫХ ЦЕЛЕЙ. Подробнее см. в Стандартной
    общественной лицензии GNU.

    Вы должны были получить копию Стандартной общественной лицензии GNU
    вместе с этой программой. Если это не так, см.
    <https://www.gnu.org/licenses/>.
*/

package ru.malik.elaborarer.avtoo.compiler;

import avt.io.*;
import avt.lang.array.*;
import avt.util.*;
import platform.independent.filesystem.*;
import platform.independent.streamformat.*;
import ru.malik.elaborarer.avtoo.lang.*;

public class TableBuilder(Project, AVTOOConstants, AVTOORecompilable, AVTOOService)
{
    /*<fold дополнительные канонические названия важных пакетов, используемых компилятором>*/
    public static final String PACKNAME_ARRAY = PACKNAME_LANG + ".array";
    /*</fold>*/

    /*<fold дополнительные простые названия важных типов, используемых компилятором>*/
    public static final String TYPENAME_RAW_DATA              =              "RawData";
    public static final String TYPENAME_CLONEABLE             =            "Cloneable";
    public static final String TYPENAME_MEASUREABLE           =          "Measureable";
    public static final String TYPENAME_IMMUTABLE_OBJECT      =      "ImmutableObject";
    public static final String TYPENAME_MUTABLE_MEASUREABLE   =   "MutableMeasureable";
    public static final String TYPENAME_IMMUTABLE_MEASUREABLE = "ImmutableMeasureable";
    /*</fold>*/

    private static void appendImpliedSuperservices(ClassType[] classes) {
        for(int length = classes == null ? 0 : classes.length, int index = 0; index < length; index++) classes[index].appendImpliedSuperservices();
    }

    private static void appendImpliedMembers(ClassType[] classesArray) {
        for(int clength = classesArray == null ? 0 : classesArray.length, int cindex = 0; cindex < clength; cindex++)
        {
            ClassType current = classesArray[cindex];
            if(!current.isStruct() && !current.isHelper())
            {
                boolean isClass = current.isClass();
                boolean hasNoConstructor = isClass && !current.isArray();
                for(LexemeSequence source = (LexemeSequence) current.source, int mlength = current.length, int mindex = 0; mindex < mlength; mindex++)
                {
                    Member member = current[mindex];
                    if(member instanceof OverriddableMember)
                    {
                        if(member.isSpecial() && member instanceof InstInit) hasNoConstructor = false;
                        continue;
                    }
                    if(member instanceof AllocatableMember)
                    {
                        int position = member.implementationPosition;
                        if(position >= 0 && source.getLexemeKind(position) == EQUALS && current.getStaticBlock() == null) current.createStaticBlock(PUBLIC | ATTR_STATIC | ATTR_SYNTHETIC, -1, -1);
                    }
                }
                if(hasNoConstructor)
                {
                    current.createConstructor(PUBLIC | ATTR_SYNTHETIC, null, -1, -1);
                }
                if(isClass || !current.isAbstract() && current.isService()) for(int slength = current.getSuperservicesLength(), int ssi = 0; ssi < slength; ssi++)
                {
                    ClassType superservice = current.getSuperserviceTypeAt(ssi);
                    label0: for(int mlength = superservice.length, int mindex = 0; mindex < mlength; mindex++)
                    {
                        Member member = superservice[mindex];
                        if(member.isAbstract())
                        {
                            OverriddableMember overriddableA = (OverriddableMember) member;
                            for(int ssj = 0; ssj < slength; ssj++) if(ssi != ssj)
                            {
                                OverriddableMember overriddableB = overriddableA.overridesIn(current.getSuperserviceTypeAt(ssj), Method.TYPE_ONLY);
                                if(overriddableB != null && overriddableB.isVisibleFrom(current, current)) continue label0;
                            }
                            OverriddableMember overriddableB = overriddableA.overridesIn(current, Method.TYPE | Method.SUPERCLASSES);
                            if(overriddableB == null || !overriddableB.isVisibleFrom(current, current))
                            {
                                if(member instanceof Method) with((Method) member)
                                {
                                    Method method = current.createMethod(attributes | ATTR_SYNTHETIC, type, specialSimpleName, arguments.clone(), -1, -1);
                                    for(int tlength = getThrowablesLength(), int tindex = 0; tindex < tlength; tindex++)
                                    {
                                        method.appendThrowable(getThrowableTypeAt(tindex), -1);
                                    }
                                    continue;
                                }
                                if(member instanceof Operator) with((Operator) member)
                                {
                                    current.createOperator(attributes | ATTR_SYNTHETIC, type, kind, arguments.clone(), -1, -1);
                                    continue;
                                }
                                with((Property) member)
                                {
                                    current.createProperty(attributes | ATTR_SYNTHETIC, type, specialSimpleName, -1, -1);
                                }
                            }
                        }
                    }
                }
            }
        }
    }

    private static void checkMembers(ClassType[] classesArray) throws SourceException {
        for(int clength = classesArray == null ? 0 : classesArray.length, int cindex = 0; cindex < clength; cindex++)
        {
            String impl = null;
            ClassType current = classesArray[cindex];
            boolean isHelper = current.isHelper();
            for(int ssi = current.getSuperservicesLength(); ssi-- > 0; ) for(ClassType superserviceA = current.getSuperserviceTypeAt(ssi), int mindex = superserviceA.length; mindex-- > 0; )
            {
                Member member = superserviceA[mindex];
                if(!member.isSynthetic() && !member.isStatic() && member.isVisibleFrom(current, current) && member instanceof OverriddableMember)
                {
                    for(OverriddableMember overriddableA = (OverriddableMember) member, int ssj = ssi; ssj-- > 0; )
                    {
                        ClassType superserviceB = current.getSuperserviceTypeAt(ssj);
                        OverriddableMember overriddableB = overriddableA.overridesIn(superserviceB, Method.TYPE_ONLY);
                        if(overriddableB != null && overriddableB.isVisibleFrom(current, current))
                        {
                            String incm = null;
                            label0:
                            {
                                if(!isCompatibleTypes(overriddableA, overriddableB))
                                {
                                    if(member instanceof Method) with((Method) member)
                                    {
                                        incm = String.format(
                                            package.getResourceString("incompatible-services.method"),
                                            new Object[] { superserviceB.specialCanonicalName, superserviceA.specialCanonicalName, current.specialSimpleName, specialSimpleName + arguments.toString() }
                                        );
                                        break label0;
                                    }
                                    if(member instanceof Operator) with((Operator) member)
                                    {
                                        incm = String.format(
                                            package.getResourceString("incompatible-services.operator"),
                                            new Object[] { superserviceB.specialCanonicalName, superserviceA.specialCanonicalName, current.specialSimpleName, symbol + arguments.toString() }
                                        );
                                        break label0;
                                    }
                                    incm = String.format(
                                        package.getResourceString("incompatible-services.property"),
                                        new Object[] { superserviceB.specialCanonicalName, superserviceA.specialCanonicalName, current.specialSimpleName, member.specialSimpleName }
                                    );
                                    break label0;
                                }
                                if(impl == null && ((overriddableB = overriddableA.overridesIn(current, Method.TYPE | Method.SUPERCLASSES)) == null || !overriddableB.isVisibleFrom(current, current)))
                                {
                                    if(member instanceof Method) with((Method) member)
                                    {
                                        impl = String.format(
                                            package.getResourceString("must-also-implemented.method"),
                                            new Object[] { superserviceB.specialCanonicalName, superserviceA.specialCanonicalName, current.specialSimpleName, specialSimpleName + arguments.toString() }
                                        );
                                        continue;
                                    }
                                    if(member instanceof Operator) with((Operator) member)
                                    {
                                        impl = String.format(
                                            package.getResourceString("must-also-implemented.operator"),
                                            new Object[] { superserviceB.specialCanonicalName, superserviceA.specialCanonicalName, current.specialSimpleName, symbol + arguments.toString() }
                                        );
                                        continue;
                                    }
                                    impl = String.format(
                                        package.getResourceString("must-also-implemented.property"),
                                        new Object[] { superserviceB.specialCanonicalName, superserviceA.specialCanonicalName, current.specialSimpleName, member.specialSimpleName }
                                    );
                                    continue;
                                }
                            }
                            if(incm != null)
                            {
                                TextSource source = (TextSource) current.source;
                                throw source == null ? new SourceException(incm) : new TextSourceException(incm) { source = source, position = current.declarationPosition };
                            }
                        }
                    }
                }
            }
            if(impl != null)
            {
                TextSource source = (TextSource) current.source;
                throw source == null ? new SourceException(impl) : new TextSourceException(impl) { source = source, position = current.declarationPosition };
            }
            {
                ClassType superclass = current.getSuperclassType();
                if(superclass != null) for(int mindex = current.length; mindex-- > 0; )
                {
                    Member member = current[mindex];
                    if(!member.isSpecial() && !member.isSynthetic() && !member.isStatic() && member instanceof OverriddableMember)
                    {
                        OverriddableMember overriddableA = (OverriddableMember) member;
                        OverriddableMember overriddableB = overriddableA.overridesIn(superclass, Method.TYPE | Method.SUPERCLASSES);
                        if(overriddableB != null && overriddableB.isVisibleFrom(current, current)) checkOverriddable(current, overriddableA, overriddableB);
                    }
                }
            }
            for(int sindex = current.getSuperservicesLength(); sindex-- > 0; )
            {
                ClassType superservice = current.getSuperserviceTypeAt(sindex);
                for(int mindex = superservice.length; mindex-- > 0; )
                {
                    Member member = superservice[mindex];
                    if(!member.isSynthetic() && !member.isStatic() && member.isVisibleFrom(current, current) && member instanceof OverriddableMember)
                    {
                        OverriddableMember overriddableA = (OverriddableMember) member;
                        OverriddableMember overriddableB = overriddableA.overridesIn(current, Method.TYPE | Method.SUPERCLASSES);
                        if(overriddableB != null && overriddableB.isVisibleFrom(current, current)) checkOverriddable(current, overriddableB, overriddableA);
                    }
                }
            }
            if(!isHelper && !current.isAbstract())
            {
                ClassType superclass = current;
                do
                {
                    for(int mlength = superclass.length, int mindex = 0; mindex < mlength; mindex++)
                    {
                        Member member = superclass[mindex];
                        if(member.isAbstract() && member.isVisibleFrom(current, current) && ((OverriddableMember) member).overridesIn(current, Method.TYPE | Method.SUPERCLASSES).isAbstract())
                        {
                            TextSource source = (TextSource) current.source;
                            impl = String.format(package.getResourceString("must-be.abstract-type"), new Object[] { current.specialSimpleName });
                            throw source == null ? new SourceException(impl) : new TextSourceException(impl) { source = source, position = current.declarationPosition };
                        }
                    }
                } while((superclass = superclass.getSuperclassType()) != null);
            }
            for(ClassType superclass = current.getSuperclassType(); superclass != null; superclass = superclass.getSuperclassType())
            {
                for(int mlength = superclass.length, int mindex = 0; mindex < mlength; mindex++)
                {
                    Member member = superclass[mindex];
                    if(member.isAbstract() && !member.isVisibleFrom(current, current))
                    {
                        label0:
                        {
                            if(member instanceof Method) with((Method) member)
                            {
                                impl = String.format(
                                    package.getResourceString("can-not-implement.method"),
                                    new Object[] { current.specialSimpleName, superclass.specialCanonicalName, specialSimpleName + arguments.toString() }
                                );
                                break label0;
                            }
                            if(member instanceof Operator) with((Operator) member)
                            {
                                impl = String.format(
                                    package.getResourceString("can-not-implement.operator"),
                                    new Object[] { current.specialSimpleName, superclass.specialCanonicalName, symbol + arguments.toString() }
                                );
                                break label0;
                            }
                            impl = String.format(
                                package.getResourceString("can-not-implement.property"),
                                new Object[] { current.specialSimpleName, superclass.specialCanonicalName, member.specialSimpleName }
                            );
                        }
                        if(impl != null)
                        {
                            TextSource source = (TextSource) current.source;
                            throw source == null ? new SourceException(impl) : new TextSourceException(impl) { source = source, position = current.declarationPosition };
                        }
                    }
                }
            }
            if(isHelper) for(ClassType target = current.getHelperForType(), int mlength = current.length, int mindex = 0; mindex < mlength; mindex++)
            {
                Member hmember = current[mindex];
                Member tmember = !hmember.isStatic() && hmember instanceof OverriddableMember ? (
                    ((OverriddableMember) hmember).overridesIn(target, Method.TYPE | Method.SUPERTYPES)
                ) : hmember instanceof Callable ? (
                    target.getChildCallable(hmember.specialSimpleName, ((Callable) hmember).arguments.clone())
                ) : (
                    target.getChildMember(hmember.specialSimpleName)
                );
                if(tmember != null && tmember.isVisibleFrom(current, current))
                {
                    label0:
                    {
                        if(hmember instanceof Method) with((Method) hmember)
                        {
                            impl = String.format(package.getResourceString("can-not-reference.method"), new Object[] { target.specialSimpleName, specialSimpleName + arguments.toString() });
                            break label0;
                        }
                        if(hmember instanceof Operator) with((Operator) hmember)
                        {
                            impl = String.format(package.getResourceString("can-not-reference.operator"), new Object[] { target.specialSimpleName, symbol + arguments.toString() });
                            break label0;
                        }
                        impl = String.format(
                            package.getResourceString(hmember instanceof Property ? "can-not-reference.property" : "can-not-reference.field"),
                            new Object[] { target.specialSimpleName, hmember.specialSimpleName }
                        );
                    }
                    if(impl != null)
                    {
                        TextSource source = (TextSource) current.source;
                        throw source == null ? new SourceException(impl) : new TextSourceException(impl) { source = source, position = hmember.declarationPosition };
                    }
                }
            }
        }
    }

    private static void checkSuperservices(ClassType[] classesArray) throws SourceException {
        for(int clength = classesArray == null ? 0 : classesArray.length, int cindex = 0; cindex < clength; cindex++)
        {
            ClassType current = classesArray[cindex];
            if(current.isService())
            {
                int sindex = current.getSuperserviceIndex(current);
                if(sindex >= 0)
                {
                    Object source = current.source;
                    if(source instanceof BinarySource)
                    {
                        BinarySource bin = (BinarySource) source;
                        throw new BinarySourceException(String.format(
                            package.getResourceString("cyclic-inheritance"), new Object[] { current.specialCanonicalName }
                        )) { source = bin, offset = bin.chunks[current.declarationPosition].dataOffsetToSourceOffset(7 + (sindex << 1)) };
                    }
                    if(source instanceof TextSource)
                    {
                        int position = current.getSuperservicePositionAt(sindex);
                        while(position < 0 && sindex >= 0) if((--sindex < 0 ? current.getSuperclassType() : current.getSuperserviceTypeAt(sindex)).isSuperservice(current))
                        {
                            position = sindex < 0 ? current.getSuperclassPosition() : current.getSuperservicePositionAt(sindex);
                        }
                        throw new TextSourceException(String.format(
                            package.getResourceString("cyclic-inheritance"), new Object[] { current.specialCanonicalName }
                        )) { source = (TextSource) source, position = position };
                    }
                    throw new SourceException(String.format(package.getResourceString("cyclic-inheritance"), new Object[] { current.specialCanonicalName }));
                }
            }
            int slength = current.getSuperservicesLength();
            for(int ssi = slength; ssi-- > 1; ) for(ClassType superserviceA = current.getSuperserviceTypeAt(ssi), ClassType superclassA = superserviceA.getSuperclassType(), int ssj = ssi; ssj-- > 0; )
            {
                ClassType superserviceB = current.getSuperserviceTypeAt(ssj);
                ClassType superclassB = superserviceB.getSuperclassType();
                if(superclassA != superclassB && !superclassA.isSuperclass(superclassB) && !superclassB.isSuperclass(superclassA))
                {
                    Object source = current.source;
                    if(source instanceof BinarySource)
                    {
                        BinarySource bin = (BinarySource) source;
                        throw new BinarySourceException(String.format(
                            package.getResourceString("incompatible-services.superclass"),
                            new Object[] { superserviceB.specialCanonicalName, superserviceA.specialCanonicalName, superclassB.specialCanonicalName, superclassA.specialCanonicalName }
                        )) { source = bin, offset = bin.chunks[current.declarationPosition].dataOffsetToSourceOffset(3) };
                    }
                    if(source instanceof TextSource)
                    {
                        throw new TextSourceException(String.format(
                            package.getResourceString("incompatible-services.superclass"),
                            new Object[] { superserviceB.specialCanonicalName, superserviceA.specialCanonicalName, superclassB.specialCanonicalName, superclassA.specialCanonicalName }
                        )) { source = (TextSource) source, position = current.declarationPosition + 1 };
                    }
                    throw new SourceException(String.format(
                        package.getResourceString("incompatible-services.superclass"),
                        new Object[] { superserviceB.specialCanonicalName, superserviceA.specialCanonicalName, superclassB.specialCanonicalName, superclassA.specialCanonicalName }
                    ));
                }
            }
            if(slength > 0)
            {
                ClassType superclassA = current.getSuperserviceTypeAt(0).getSuperclassType();
                for(int sindex = 1; sindex < slength; sindex++)
                {
                    ClassType superclassB = current.getSuperserviceTypeAt(sindex).getSuperclassType();
                    if(superclassB.isSuperclass(superclassA)) superclassA = superclassB;
                }
                ClassType superclassB = current.getSuperclassType();
                if(superclassB != superclassA && !superclassB.isSuperclass(superclassA))
                {
                    Object source = current.source;
                    if(source instanceof BinarySource)
                    {
                        BinarySource bin = (BinarySource) source;
                        throw new BinarySourceException(String.format(
                            package.getResourceString("must-be.superclass"), new Object[] { superclassA.specialCanonicalName }
                        )) { source = bin, offset = bin.chunks[current.declarationPosition].dataOffsetToSourceOffset(5) };
                    }
                    if(source instanceof TextSource)
                    {
                        throw new TextSourceException(String.format(
                            package.getResourceString("must-be.superclass"), new Object[] { superclassA.specialCanonicalName }
                        )) { source = (TextSource) source, position = current.declarationPosition + 2 };
                    }
                    throw new SourceException(String.format(package.getResourceString("must-be.superclass"), new Object[] { superclassA.specialCanonicalName }));
                }
            }
        }
    }

    private static void checkSuperclasses(ClassType[] classesArray, ClassType[] bufferArray) throws SourceException {
        for(int clength = classesArray == null ? 0 : classesArray.length, int cindex = 0; cindex < clength; cindex++)
        {
            ClassType current = classesArray[cindex];
            int blength = 1;
            bufferArray[0] = current;
            for(ClassType superclass = current.getSuperclassType(); superclass != null; superclass = superclass.getSuperclassType())
            {
                if(Array.indexOf(superclass, bufferArray, 0, blength) >= 0)
                {
                    Object source = superclass.source;
                    if(source instanceof BinarySource)
                    {
                        BinarySource bin = (BinarySource) source;
                        throw new BinarySourceException(String.format(
                            package.getResourceString("cyclic-inheritance"), new Object[] { superclass.specialCanonicalName }
                        )) { source = bin, offset = bin.chunks[superclass.declarationPosition].dataOffsetToSourceOffset(3) };
                    }
                    if(source instanceof TextSource)
                    {
                        throw new TextSourceException(String.format(
                            package.getResourceString("cyclic-inheritance"), new Object[] { superclass.specialCanonicalName }
                        )) { source = (TextSource) source, position = superclass.getSuperclassPosition() };
                    }
                    throw new SourceException(String.format(package.getResourceString("cyclic-inheritance"), new Object[] { superclass.specialCanonicalName }));
                }
                bufferArray[blength++] = superclass;
            }
        }
    }

    private static void checkOverriddable(ClassType current, OverriddableMember overridding, OverriddableMember overridden) throws SourceException {
        /* overridding – переопределяющий член */
        /* overridden  – переопределённый член */
        String ovrr = null;
        int position = -1;
        label0:
        {
            Property property = null;
            if(overridding.visibility < overridden.visibility)
            {
                if(overridding instanceof Method) with((Method) overridding)
                {
                    ovrr = String.format(
                        package.getResourceString("override.incompatible-visibility.method"),
                        new Object[] { overridden.parentType.specialCanonicalName, current.specialSimpleName, specialSimpleName + arguments.toString() }
                    );
                    break label0;
                }
                if(overridding instanceof Operator) with((Operator) overridding)
                {
                    ovrr = String.format(
                        package.getResourceString("override.incompatible-visibility.operator"),
                        new Object[] { overridden.parentType.specialCanonicalName, current.specialSimpleName, symbol + arguments.toString() }
                    );
                    break label0;
                }
                ovrr = String.format(
                    package.getResourceString("override.incompatible-visibility.property"),
                    new Object[] { overridden.parentType.specialCanonicalName, current.specialSimpleName, overridding.specialSimpleName }
                );
                break label0;
            }
            if(overridden.isFinal())
            {
                if(overridding instanceof Method) with((Method) overridding)
                {
                    ovrr = String.format(
                        package.getResourceString("override.final.method"),
                        new Object[] { overridden.parentType.specialCanonicalName, current.specialSimpleName, specialSimpleName + arguments.toString() }
                    );
                    break label0;
                }
                if(overridding instanceof Operator) with((Operator) overridding)
                {
                    ovrr = String.format(
                        package.getResourceString("override.final.operator"),
                        new Object[] { overridden.parentType.specialCanonicalName, current.specialSimpleName, symbol + arguments.toString() }
                    );
                    break label0;
                }
                ovrr = String.format(
                    package.getResourceString("override.final.property"),
                    new Object[] { overridden.parentType.specialCanonicalName, current.specialSimpleName, overridding.specialSimpleName }
                );
                break label0;
            }
            if(overridden instanceof Property && (property = (Property) overridden).hasWrite() ? overridden.type != overridding.type : !overridden.type.isAssignableFrom(overridding.type))
            {
                if(overridding instanceof Method) with((Method) overridding)
                {
                    ovrr = String.format(
                        package.getResourceString("override.incompatible-type.method"),
                        new Object[] { overridden.parentType.specialCanonicalName, current.specialSimpleName, specialSimpleName + arguments.toString() }
                    );
                    break label0;
                }
                if(overridding instanceof Operator) with((Operator) overridding)
                {
                    ovrr = String.format(
                        package.getResourceString("override.incompatible-type.operator"),
                        new Object[] { overridden.parentType.specialCanonicalName, current.specialSimpleName, symbol + arguments.toString() }
                    );
                    break label0;
                }
                ovrr = String.format(
                    package.getResourceString("override.incompatible-type.property"),
                    new Object[] { overridden.parentType.specialCanonicalName, current.specialSimpleName, overridding.specialSimpleName }
                );
                break label0;
            }
            if(overridding instanceof Method) with((Method) overridding)
            {
                String name = null;
                label2:
                {
                    for(Method method = (Method) overridden, int tlength = getThrowablesLength(), int tindex = 0; tindex < tlength; tindex++)
                    {
                        ClassType type = getThrowableTypeAt(tindex);
                        if(!method.canThrown(type))
                        {
                            name = type.specialCanonicalName;
                            position = getThrowablePositionAt(tindex);
                            break label2;
                        }
                    }
                    return;
                }
                ovrr = String.format(
                    package.getResourceString("override.can-not.throws.method"),
                    new Object[] { overridden.parentType.specialCanonicalName, current.specialSimpleName, specialSimpleName + arguments.toString(), name }
                );
                break label0;
            }
            if(overridding instanceof Property) with((Property) overridding)
            {
                if(!hasRead() && property.hasRead())
                {
                    ovrr = String.format(
                        package.getResourceString("override.must-have.property.read"),
                        new Object[] { overridden.parentType.specialCanonicalName, current.specialSimpleName, specialSimpleName }
                    );
                    break label0;
                }
                if(!hasWrite() && property.hasWrite())
                {
                    ovrr = String.format(
                        package.getResourceString("override.must-have.property.write"),
                        new Object[] { overridden.parentType.specialCanonicalName, current.specialSimpleName, specialSimpleName }
                    );
                }
            }
        }
        if(ovrr != null)
        {
            TextSource source = (TextSource) current.source;
            if(position < 0)
            {
                position = overridding.declarationPosition;
                if(current != overridding.parentType || position < 0) position = current.declarationPosition;
            }
            throw source == null ? new SourceException(ovrr) : new TextSourceException(ovrr) { source = source, position = position };
        }
    }

    private static boolean isCompatibleTypes(OverriddableMember overriddableA, OverriddableMember overriddableB) {
        if(overriddableA instanceof Property)
        {
            if(((Property) overriddableA).hasWrite())
            {
                if(((Property) overriddableB).hasWrite())
                {
                    return overriddableA.type == overriddableB.type;
                }
                return overriddableB.type.isAssignableFrom(overriddableA.type);
            }
            if(((Property) overriddableB).hasWrite())
            {
                return overriddableA.type.isAssignableFrom(overriddableB.type);
            }
        }
        return overriddableA.type.isCompatibleWith(overriddableB.type);
    }

    private static int skipPropertySpecifier(TextSource source, int position) throws TextSourceException {
        int kind = source.getLexemeKind(position);
        if(kind == COMMA || kind == CURLY_CLOSED)
        {
            throw new TextSourceException(package.getResourceString("expected.property-specifier")) { source = source, position = position };
        }
        for(int parenth = 0, int bracket = 0, int curly = 0; kind != COMMA && kind != CURLY_CLOSED || (curly | bracket | parenth) != 0; kind = source.getLexemeKind(++position)) switch(kind)
        {
        case CURLY_OPENED:
            curly++;
            break;
        case CURLY_CLOSED:
            if(curly-- == 0)
            {
                throw new TextSourceException(package.getResourceString("extra.curly")) { source = source, position = position };
            }
            break;
        case BRACKET_OPENED:
            bracket++;
            break;
        case BRACKET_CLOSED:
            if(bracket-- == 0)
            {
                throw new TextSourceException(package.getResourceString("extra.bracket")) { source = source, position = position };
            }
            break;
        case PARENTH_OPENED:
            parenth++;
            break;
        case PARENTH_CLOSED:
            if(parenth-- == 0)
            {
                throw new TextSourceException(package.getResourceString("extra.parenth")) { source = source, position = position };
            }
            break;
        case L_END:
            if(curly > 0)
            {
                throw new TextSourceException(package.getResourceString("not-closed.curly")) { source = source, position = position };
            }
            if(bracket > 0)
            {
                throw new TextSourceException(package.getResourceString("not-closed.bracket")) { source = source, position = position };
            }
            if(parenth > 0)
            {
                throw new TextSourceException(package.getResourceString("not-closed.parenth")) { source = source, position = position };
            }
            throw new TextSourceException(package.getResourceString("unexpected-end.source")) { source = source, position = position };
        }
        return position;
    }

    private Library fldProject;
    private LanguageLexer fldLanguageLexer;
    private DocumentLexer fldDocumentationLexer;

    public (int pointerSize): super(pointerSize) {  }

    public void compile() throws IOException, CompilerException {
        /* -- предыдущие стадии -- */
        super.compile();
        /* 2. Стадия чтения и анализа исходных кодов */
        Library[] libraries = libraries.clone();
        int llength = libraries.length;
        if(llength <= 0)
        {
            throw new CompilerException(package.getResourceString("not-specified.project"));
        }
        int slengthOfLibrary = 0;
        Source[] sourcesOfLibrary = null;
        Source[] sourcesOfProject = null;
        Library project = fldProject;
        for(int lindex = 0; lindex < llength; lindex++)
        {
            Library library = libraries[lindex];
            Source[] sources = library.sources.clone();
            int slength = sources.length;
            if(library == project)
            {
                sourcesOfProject = sources;
            }
            else if(sourcesOfLibrary == null)
            {
                Array.copy(sources, 0, sourcesOfLibrary = new Source[getBestArrayCapacity(slengthOfLibrary = slength)], 0, slengthOfLibrary);
            }
            else
            {
                int nlength = slengthOfLibrary + slength;
                if(sourcesOfLibrary.length < nlength) Array.copy(sourcesOfLibrary, 0, sourcesOfLibrary = new Source[getBestArrayCapacity(nlength)], 0, slengthOfLibrary);
                Array.copy(sources, 0, sourcesOfLibrary, slengthOfLibrary, slength);
                slengthOfLibrary = nlength;
            }
            for(int sindex = 0; sindex < slength; sindex++)
            {
                sources[sindex].parseInputStream();
            }
        }
        if(slengthOfLibrary != (sourcesOfLibrary == null ? 0 : sourcesOfLibrary.length))
        {
            Array.copy(sourcesOfLibrary, 0, sourcesOfLibrary = new Source[slengthOfLibrary], 0, slengthOfLibrary);
        }
        with(new CompilerParallelWorker(maxThreads))
        {
            targets = sourcesOfLibrary;
            run(new TableBuilderSourcesReader(this));
            targets = sourcesOfProject;
            run(new TableBuilderSourcesLexer(languageLexer));
            run(new TableBuilderSourcesParser());
        }
        int slengthOfProject = sourcesOfProject.length;
        /* 3. Стадия поиска пакетов */
        libraries[0].createPackage(PUBLIC, "", null, -1, -1);
        for(int sindex = 0; sindex < slengthOfLibrary; sindex++)
        {
            BinarySource source = (BinarySource) sourcesOfLibrary[sindex];
            Object[] constants = (Object[]) source[1];
            for(ChunkArray chunks = source.chunks, int clength = chunks.length - 1, int cindex = 2; cindex < clength; cindex++) with(chunks[cindex]) if(type == CHUNK_PACK)
            {
                int attributes = readUnsignedShort();
                int specialCanonicalName = readInt();
                source[cindex] = source.parentLibrary.createPackage(attributes, (String) constants[specialCanonicalName], source, cindex, -1);
            }
        }
        StringBuilder name = new StringBuilder(LIMIT_NAME_LENGTH);
        for(int sindex = 0; sindex < slengthOfProject; sindex++)
        {
            TextSource source = (TextSource) sourcesOfProject[sindex];
            if(isPackageSourceFileName(source.outputPath))
            {
                int position = 0;
                int visibility = PRIVATE;
                /* документация */
                int documentationPosition = -1;
                if(source.getLexemeKind(0) == L_DOC)
                {
                    documentationPosition = 0;
                    position = 1;
                }
                /* видимость */
                switch(source.getLexemeKind(position))
                {
                case PROTECTED:
                    visibility = PROTECTED;
                    /* падение через */
                case PRIVATE:
                    position++;
                    break;
                case PUBLIC:
                case PUBLISHED:
                    visibility = PUBLIC;
                    position++;
                }
                /* пакет */
                if(source.getLexemeKind(position) != PACKAGE)
                {
                    throw new TextSourceException(package.getResourceString("expected.package")) { source = source, position = position };
                }
                /* название */
                int declarationPosition = ++position;
                if(source.getLexemeKind(position = parsePackageName(source, position, name)) != L_END)
                {
                    throw new TextSourceException(package.getResourceString("extra.chars.source")) { source = source, position = position };
                }
                /* проверки */
                Package conflictItem;
                String specialCanonicalName = name.toString();
                if((conflictItem = getPackage(specialCanonicalName, false)) != null)
                {
                    throw new TextSourceException(String.format(
                        package.getResourceString("duplicate.package"), new Object[] { conflictItem.specialCanonicalName }
                    )) { source = source, position = declarationPosition };
                }
                if((conflictItem = getPackage(specialCanonicalName, true)) != null)
                {
                    throw new TextSourceException(String.format(
                        package.getResourceString("conflict.package-package"), new Object[] { conflictItem.specialCanonicalName }
                    )) { source = source, position = declarationPosition };
                }
                /* создание пакета */
                project.createPackage(visibility, specialCanonicalName, source, declarationPosition, documentationPosition);
                name.clear();
            }
        }
        for(int sindex = 0; sindex < slengthOfProject; sindex++)
        {
            TextSource source = (TextSource) sourcesOfProject[sindex];
            if(isTypeSourceFileName(source.outputPath))
            {
                /* секция пакета */
                if(source.getLexemeKind(0) != PACKAGE)
                {
                    throw new TextSourceException(package.getResourceString("expected.package")) { source = source, position = 0 };
                }
                int position = parsePackageName(source, 1, name);
                if(source.getLexemeKind(position) != SEMICOLON)
                {
                    throw new TextSourceException(package.getResourceString("expected.semicolon")) { source = source, position = position };
                }
                /* проверки */
                Package conflictItem;
                String specialCanonicalName = name.toString();
                if((conflictItem = getPackage(specialCanonicalName)) != null)
                {
                    if(conflictItem.parentLibrary != project)
                    {
                        throw new TextSourceException(String.format(
                            package.getResourceString("duplicate.package.another-library"), new Object[] { conflictItem.specialCanonicalName }
                        )) { source = source, position = 1 };
                    }
                } else
                {
                    if((conflictItem = getPackage(specialCanonicalName, true)) != null)
                    {
                        throw new TextSourceException(String.format(
                            package.getResourceString("conflict.package-package"), new Object[] { conflictItem.specialCanonicalName }
                        )) { source = source, position = 1 };
                    }
                    conflictItem = project.createPackage(PRIVATE, specialCanonicalName, null, -1, -1);
                }
                /* связывание пакета */
                source.owner = conflictItem;
                name.clear();
            }
        }
        /* 4. Стадия поиска типов */
        for(createPrimitiveTypes(), int sindex = 0; sindex < slengthOfLibrary; sindex++)
        {
            BinarySource source = (BinarySource) sourcesOfLibrary[sindex];
            Object[] constants = (Object[]) source[1];
            for(String outputPath = null, ChunkArray chunks = source.chunks, int clength = chunks.length - 1, int cindex = 2; cindex < clength; cindex++) with(chunks[cindex]) switch(type)
            {
            case CHUNK_SURC:
                char[] chars = new char[length];
                readFully(chars);
                outputPath = new String(chars);
                break;
            case CHUNK_TYPE:
                int attributes = readUnsignedShort();
                int parentPackage = readInt();
                int specialSimpleName = readInt();
                source[cindex] = ((PackageElement) constants[parentPackage]).getItem().createClassType(attributes, (String) constants[specialSimpleName], source, cindex, -1, outputPath);
            }
        }
        for(int sindex = 0; sindex < slengthOfProject; sindex++)
        {
            TableBuilderTextSource source = (TableBuilderTextSource) sourcesOfProject[sindex];
            if(isTypeSourceFileName(source.outputPath))
            {
                for(Package owner = source.owner, int[][] tree = source.parsingTree, int tlength = tree.length, int tindex = 1; tindex < tlength; tindex++)
                {
                    int attributes = 0;
                    int position = tree[tindex][0];
                    /* документация */
                    int documentationPosition = -1;
                    if(source.getLexemeKind(position) == L_DOC) documentationPosition = position++;
                    /* видимость */
                    int kind = source.getLexemeKind(position);
                    int visibilityPosition = position;
                    switch(kind)
                    {
                    default:
                        attributes |= SOURCE;
                        break;
                    case PRIVATE:
                    case PROTECTED:
                        throw new TextSourceException(package.getResourceString("unsupported-visibility.type")) { source = source, position = position };
                    case PACKAGE:
                    case PUBLIC:
                    case PUBLISHED:
                        attributes |= kind;
                        position++;
                    }
                    /* абстрактность */
                    int bindingPosition = position;
                    switch(source.getLexemeKind(position))
                    {
                    case ABSTRACT:
                        attributes |= ATTR_ABSTRACT;
                        position++;
                        break;
                    case FINAL:
                        attributes |= ATTR_FINAL;
                        position++;
                    }
                    /* разновидность */
                    switch(source.getLexemeKind(position))
                    {
                    default:
                        throw new TextSourceException(package.getResourceString("expected.keyword.type")) { source = source, position = position };
                    case HELPER:
                        if((attributes & ATTR_ABSTRACT) != 0)
                        {
                            throw new TextSourceException(package.getResourceString("unsupported-modifiers.abstract.helper")) { source = source, position = bindingPosition };
                        }
                        attributes |= ATTR_FINAL | ATTR_SERVICE;
                        position++;
                        break;
                    case INTERFACE:
                        if((attributes & ATTR_FINAL) != 0)
                        {
                            throw new TextSourceException(package.getResourceString("unsupported-modifiers.final.interface")) { source = source, position = bindingPosition };
                        }
                        attributes |= ATTR_INTERFACE | ATTR_ABSTRACT;
                        position++;
                        break;
                    case SERVICE:
                        if((attributes & ATTR_FINAL) != 0)
                        {
                            throw new TextSourceException(package.getResourceString("unsupported-modifiers.final.service")) { source = source, position = bindingPosition };
                        }
                        attributes |= ATTR_SERVICE;
                        position++;
                        break;
                    case STRUCT:
                        if((attributes & ATTR_ABSTRACT) != 0)
                        {
                            throw new TextSourceException(package.getResourceString("unsupported-modifiers.abstract.struct")) { source = source, position = bindingPosition };
                        }
                        attributes |= ATTR_STRUCT;
                        /* падение через */
                    case CLASS:
                        position++;
                    }
                    /* название */
                    if(source.getLexemeKind(position) != L_NAME)
                    {
                        throw new TextSourceException(package.getResourceString("expected.name.type")) { source = source, position = position };
                    }
                    String specialSimpleName = source.getLexemeString(position);
                    String specialCanonicalName = owner.specialCanonicalName;
                    /* проверки */
                    if(
                        attributes != PUBLIC &&
                        PACKNAME_LANG.equals(specialCanonicalName) &&
                        (TYPENAME_OBJECT.equals(specialSimpleName) || TYPENAME_STRUCT.equals(specialSimpleName) || TYPENAME_THROWABLE.equals(specialSimpleName))
                    )
                    {
                        throw new TextSourceException(package.getResourceString("can-be.public-class")) { source = source, position = visibilityPosition };
                    }
                    ProgrammeItem conflictItem;
                    if((conflictItem = owner.getChildType(specialSimpleName, false)) != null)
                    {
                        throw new TextSourceException(String.format(
                            package.getResourceString("duplicate.name.type"), new Object[] { specialSimpleName }
                        )) { source = source, position = position };
                    }
                    if((conflictItem = owner.getChildType(specialSimpleName, true)) != null)
                    {
                        throw new TextSourceException(String.format(
                            package.getResourceString("conflict.type-type"), new Object[] { conflictItem.specialSimpleName }
                        )) { source = source, position = position };
                    }
                    if((conflictItem = getPackage((name + specialCanonicalName + '.' + specialSimpleName).toString(), false)) != null)
                    {
                        throw new TextSourceException(String.format(
                            package.getResourceString("conflict.type-package"), new Object[] { conflictItem.specialSimpleName }
                        )) { source = source, position = position };
                    }
                    name.clear();
                    /* создание типа */
                    owner.createClassType(attributes, specialSimpleName, source, position, documentationPosition, source.outputPath);
                }
            }
        }
        for(checkEssentialTypesPresence(), int sindex = 0; sindex < slengthOfProject; sindex++)
        {
            TableBuilderTextSource source = (TableBuilderTextSource) sourcesOfProject[sindex];
            if(isTypeSourceFileName(source.outputPath))
            {
                int position = source.parsingTree[0][0];
                if(position >= 0) for(; source.getLexemeKind(position) == IMPORT; position++)
                {
                    if(source.getLexemeKind(++position) != L_NAME)
                    {
                        throw new TextSourceException(package.getResourceString("expected.name.package")) { source = source, position = position };
                    }
                    name + source.getLexemeString(position);
                    if(source.getLexemeKind(++position) != PERIOD)
                    {
                        throw new TextSourceException(package.getResourceString("expected.period")) { source = source, position = position };
                    }
                    boolean isPackage = false;
                    label0: do
                    {
                        switch(source.getLexemeKind(++position))
                        {
                        default:
                            throw new TextSourceException(package.getResourceString("expected.name-or-star")) { source = source, position = position };
                        case O_SCAL_MUL:
                            if(source.getLexemeKind(++position) != SEMICOLON)
                            {
                                throw new TextSourceException(package.getResourceString("expected.semicolon")) { source = source, position = position };
                            }
                            isPackage = true;
                            break label0;
                        case L_NAME:
                            name + '.' + source.getLexemeString(position);
                        }
                        switch(source.getLexemeKind(++position))
                        {
                        default:
                            throw new TextSourceException(package.getResourceString("expected.period-or-semicolon")) { source = source, position = position };
                        case SEMICOLON:
                            break label0;
                        case PERIOD:
                        }
                    } while(true);
                    RequiredReflectItem item;
                    String specialCanonicalName = name.toString();
                    if(isPackage)
                    {
                        Package pack = getPackage(specialCanonicalName);
                        if((item = pack) == null)
                        {
                            throw new TextSourceException(String.format(
                                package.getResourceString("not-found.package"), new Object[] { specialCanonicalName }
                            )) { source = source, position = position };
                        }
                        if(source.isImported(pack))
                        {
                            throw new TextSourceException(String.format(
                                package.getResourceString("package.already.imported"), new Object[] { specialCanonicalName }
                            )) { source = source, position = position };
                        }
                        if(!item.isVisibleFrom(source.declared[0]))
                        {
                            throw new TextSourceException(String.format(
                                package.getResourceString("invisible.package"), new Object[] { specialCanonicalName }
                            )) { source = source, position = position };
                        }
                    } else
                    {
                        if((item = getClassType(specialCanonicalName)) == null)
                        {
                            throw new TextSourceException(String.format(
                                package.getResourceString("not-found.type"), new Object[] { specialCanonicalName }
                            )) { source = source, position = position };
                        }
                        String specialSimpleName = item.specialSimpleName;
                        if(source.getImportedType(specialSimpleName) != null)
                        {
                            throw new TextSourceException(String.format(
                                package.getResourceString("type.already.imported"), new Object[] { specialSimpleName }
                            )) { source = source, position = position };
                        }
                        if(source.getDeclaredType(specialSimpleName) != null)
                        {
                            throw new TextSourceException(String.format(
                                package.getResourceString("type.already.contained"), new Object[] { specialSimpleName }
                            )) { source = source, position = position };
                        }
                        if(!item.isVisibleFrom(source.declared[0]))
                        {
                            throw new TextSourceException(String.format(
                                package.getResourceString("invisible.type"), new Object[] { specialCanonicalName }
                            )) { source = source, position = position };
                        }
                    }
                    source.appendImported(item);
                    name.clear();
                }
            }
        }
        {
            ClassType typeObject = getClassType(PACKNAME_LANG + "." + TYPENAME_OBJECT);
            ClassType typeStruct = getClassType(PACKNAME_LANG + "." + TYPENAME_STRUCT);
            for(int sindex = 0; sindex < slengthOfLibrary; sindex++)
            {
                BinarySource source = (BinarySource) sourcesOfLibrary[sindex];
                Object[] constants = (Object[]) source[1];
                for(ChunkArray chunks = source.chunks, int clength = chunks.length - 1, int cindex = 2; cindex < clength; cindex++) with(chunks[cindex]) if(type == CHUNK_TYPE)
                {
                    ClassType enclosing = (ClassType) source[cindex];
                    int specialCanonicalName = readInt();
                    if(enclosing.isHelper())
                    {
                        enclosing.initHelperFor(getClassType((String) constants[specialCanonicalName]), -1);
                    }
                    else if(specialCanonicalName > 0)
                    {
                        enclosing.initSuperclass(getClassType((String) constants[specialCanonicalName]), -1);
                        while(available() > 0)
                        {
                            specialCanonicalName = readInt();
                            enclosing.appendSuperservice(getClassType((String) constants[specialCanonicalName]), -1);
                        }
                    }
                    else if(enclosing.isStruct())
                    {
                        enclosing.initSuperclass(typeStruct, -1);
                    }
                    else if(enclosing != typeObject)
                    {
                        enclosing.initSuperclass(typeObject, -1);
                    }
                }
            }
            for(TableBuilderClassTypeHolder supertypeHolder = new TableBuilderClassTypeHolder(), int sindex = 0; sindex < slengthOfProject; sindex++)
            {
                TextSource source = (TextSource) sourcesOfProject[sindex];
                for(ClassTypeArray declared = source.declared, int clength = declared.length, int cindex = 0; cindex < clength; cindex++)
                {
                    ClassType enclosing = declared[cindex];
                    int position = enclosing.declarationPosition + 1;
                    switch(source.getLexemeKind(position))
                    {
                    default:
                        if(enclosing.isHelper())
                        {
                            throw new TextSourceException(package.getResourceString("expected.colon")) { source = source, position = position };
                        }
                        if(enclosing.isStruct())
                        {
                            enclosing.initSuperclass(typeStruct, -1);
                        }
                        else if(enclosing != typeObject)
                        {
                            enclosing.initSuperclass(typeObject, -1);
                        }
                        break;
                    case COLON:
                        if(enclosing.isHelper())
                        {
                            int supertypePosition = position + 1;
                            position = parseClassName(source, supertypePosition, enclosing, supertypeHolder);
                            ClassType supertypeReference = supertypeHolder.resultClassType;
                            if(supertypeReference.visibility < enclosing.visibility)
                            {
                                throw new TextSourceException(String.format(
                                    package.getResourceString("can-not-be.lower-visibility.target-type"), new Object[] { enclosing.specialSimpleName }
                                )) { source = source, position = supertypePosition };
                            }
                            enclosing.initHelperFor(supertypeReference, supertypePosition);
                        }
                        break;
                    case PARENTH_OPENED:
                        if(enclosing.isHelper())
                        {
                            throw new TextSourceException(package.getResourceString("expected.colon")) { source = source, position = position };
                        }
                        if(enclosing == typeObject)
                        {
                            throw new TextSourceException(String.format(
                                package.getResourceString("can-not-have.supertypes"), new Object[] { PACKNAME_LANG + "." + TYPENAME_OBJECT }
                            )) { source = source, position = position };
                        }
                        label0: for(boolean hasSuperclass = false; ; )
                        {
                            int supertypePosition = position + 1;
                            position = parseClassName(source, supertypePosition, enclosing, supertypeHolder);
                            ClassType supertypeReference = supertypeHolder.resultClassType;
                            if(supertypeReference.visibility < enclosing.visibility)
                            {
                                throw new TextSourceException(String.format(
                                    package.getResourceString("can-not-be.lower-visibility.supertype"), new Object[] { enclosing.specialSimpleName }
                                )) { source = source, position = supertypePosition };
                            }
                            if(supertypeReference.isFinal())
                            {
                                throw new TextSourceException(package.getResourceString("can-not-be.final.supertype")) { source = source, position = supertypePosition };
                            }
                            if(supertypeReference.isService())
                            {
                                if(enclosing.isStruct())
                                {
                                    throw new TextSourceException(String.format(
                                        package.getResourceString("can-be.struct-superclass"), new Object[] { PACKNAME_LANG + "." + TYPENAME_STRUCT }
                                    )) { source = source, position = supertypePosition };
                                }
                                if(enclosing.isSuperservice(supertypeReference))
                                {
                                    throw new TextSourceException(String.format(
                                        package.getResourceString("duplicate.supertype"), new Object[] { supertypeReference.specialCanonicalName }
                                    )) { source = source, position = supertypePosition };
                                }
                                if(!hasSuperclass)
                                {
                                    hasSuperclass = true;
                                    enclosing.initSuperclass(typeObject, -1);
                                }
                                enclosing.appendSuperservice(supertypeReference, supertypePosition);
                            }
                            else if(supertypeReference.isStruct())
                            {
                                if(!enclosing.isStruct())
                                {
                                    throw new TextSourceException(package.getResourceString("can-be.class-supertype")) { source = source, position = supertypePosition };
                                }
                                if(hasSuperclass)
                                {
                                    throw new TextSourceException(package.getResourceString("can-have.one-supertype")) { source = source, position = supertypePosition };
                                }
                                hasSuperclass = true;
                                enclosing.initSuperclass(supertypeReference, supertypePosition);
                            }
                            else /* if(supertypeReference.isClass()) */
                            {
                                if(enclosing.isStruct() && supertypeReference != typeStruct)
                                {
                                    throw new TextSourceException(String.format(
                                        package.getResourceString("can-be.struct-superclass"), new Object[] { PACKNAME_LANG + "." + TYPENAME_STRUCT }
                                    )) { source = source, position = supertypePosition };
                                }
                                if(hasSuperclass)
                                {
                                    throw new TextSourceException(package.getResourceString("can-have.one-superclass")) { source = source, position = supertypePosition };
                                }
                                hasSuperclass = true;
                                enclosing.initSuperclass(supertypeReference, supertypePosition);
                            }
                            switch(source.getLexemeKind(position))
                            {
                            default:
                                throw new TextSourceException(package.getResourceString("expected.comma-or-closed-parenth")) { source = source, position = position };
                            case PARENTH_CLOSED:
                                position++;
                                break label0;
                            case COMMA:
                            }
                        }
                    }
                    if(source.getLexemeKind(position) != CURLY_OPENED)
                    {
                        throw new TextSourceException(package.getResourceString("expected.opened-curly")) { source = source, position = position };
                    }
                }
            }
            createArrayTypes();
        }
        ClassType[] classes = classes.clone();
        ClassType[] arrays = arrays.clone();
        {
            ClassType[] buffer = new ClassType[classes.length + arrays.length];
            checkSuperclasses(classes, buffer);
            checkSuperclasses(arrays, buffer);
            buffer = null;
            initSubtypes();
            appendImpliedSuperservices(classes);
            appendImpliedSuperservices(arrays);
            checkSuperservices(classes);
            checkSuperservices(arrays);
            if(llength > 1)
            {
                classes = project.classes.clone();
                arrays = null;
            }
            sortTypes();
        }
        /* 5. Стадия поиска членов */
        {
            Type typeInt = getPrimitiveType(INT);
            Type typeVoid = getPrimitiveType(VOID);
            Type typeBoolean = getPrimitiveType(BOOLEAN);
            Local[] arguments = new Local[LIMIT_ARGUMENTS_LENGTH];
            for(ConstantFactory factory = getConstantFactory(), int sindex = 0; sindex < slengthOfLibrary; sindex++)
            {
                BinarySource source = (BinarySource) sourcesOfLibrary[sindex];
                Object[] constants = (Object[]) source[1];
                for(ClassType enclosing = null, ChunkArray chunks = source.chunks, int clength = chunks.length - 1, int cindex = 2; cindex < clength; cindex++) with(chunks[cindex]) switch(type)
                {
                case CHUNK_CFLD:
                    int attributes = readUnsignedShort();
                    int type = readInt();
                    int specialSimpleName = readInt();
                    int value = available() <= 0 ? -1 : readInt();
                    Field field = enclosing.createClassField(attributes, ((TypeElement) constants[type]).getItem(), (String) constants[specialSimpleName], cindex, -1);
                    source[cindex] = field;
                    if(value < 0)
                    {
                        field.closeComputing();
                        break;
                    }
                    Object element = constants[value];
                    if(element instanceof RecompilableElement) element = ((RecompilableElement) element).getItem();
                    field.openComputing();
                    try
                    {
                        field.setComputedValue(factory.createFrom(element));
                    } finally
                    {
                        field.closeComputing();
                    }
                    break;
                case CHUNK_SFLD:
                    int attributes = readUnsignedShort();
                    int type = readInt();
                    int specialSimpleName = readInt();
                    int capacity = readInt();
                    int offset = readInt();
                    source[cindex] = enclosing.createStructField(offset, ((TypeElement) constants[type]).getItem(), capacity, (String) constants[specialSimpleName], cindex, -1);
                    break;
                case CHUNK_METH:
                    int attributes = readUnsignedShort();
                    int type = readInt();
                    int specialSimpleName = readInt();
                    int length = readUnsignedShort();
                    if(length > LIMIT_ARGUMENTS_LENGTH)
                    {
                        throw new BinarySourceException(package.getResourceString("too-many.arguments")) { source = source, offset = dataOffsetToSourceOffset(position) };
                    }
                    arguments.length = LIMIT_ARGUMENTS_LENGTH;
                    for(int index = 0; index < length; index++)
                    {
                        int argumentType = readInt();
                        int argumentName = readInt();
                        arguments[index] = createLocal(false, ((TypeElement) constants[argumentType]).getItem(), (String) constants[argumentName], null, null, -1);
                    }
                    arguments.length = length;
                    String methodName = (String) constants[specialSimpleName];
                    Method method = SPECNAME_CLASS_INIT.equals(methodName) ? (
                        enclosing.createStaticBlock(attributes, cindex, -1)
                    ) : SPECNAME_INST_INIT.equals(methodName) ? (
                        enclosing.createConstructor(attributes, arguments, cindex, -1)
                    ) : (
                        enclosing.createMethod(attributes, ((TypeElement) constants[type]).getItem(), methodName, arguments, cindex, -1)
                    );
                    source[cindex] = method;
                    while(available() > 0)
                    {
                        int specialCanonicalName = readInt();
                        ClassType throwable = getClassType((String) constants[specialCanonicalName]);
                        if(throwable != null && !throwable.specialCanonicalName.equals(PACKNAME_LANG + "." + TYPENAME_THROWABLE) && !throwable.isSuperclass(PACKNAME_LANG + "." + TYPENAME_THROWABLE))
                        {
                            throw new BinarySourceException(String.format(
                                package.getResourceString("type.not-suitable.exception"), new Object[] { throwable.specialCanonicalName, PACKNAME_LANG + "." + TYPENAME_THROWABLE }
                            )) { source = source, offset = dataOffsetToSourceOffset(position) };
                        }
                        method.appendThrowable(throwable, -1);
                    }
                    break;
                case CHUNK_OPER:
                    int attributes = readUnsignedShort();
                    int type = readInt();
                    int specialSimpleName = readInt();
                    int length = readUnsignedShort();
                    if(length > LIMIT_ARGUMENTS_LENGTH)
                    {
                        throw new BinarySourceException(package.getResourceString("too-many.arguments")) { source = source, offset = dataOffsetToSourceOffset(position) };
                    }
                    arguments.length = LIMIT_ARGUMENTS_LENGTH;
                    for(int index = 0; index < length; index++)
                    {
                        int argumentType = readInt();
                        int argumentName = readInt();
                        arguments[index] = createLocal(false, ((TypeElement) constants[argumentType]).getItem(), (String) constants[argumentName], null, null, -1);
                    }
                    arguments.length = length;
                    int operatorKind = Operator.specialSimpleNameToKind((String) constants[specialSimpleName]);
                    source[cindex] = enclosing.createOperator(attributes, ((TypeElement) constants[type]).getItem(), operatorKind, arguments, cindex, -1);
                    break;
                case CHUNK_PROP:
                    int attributes = readUnsignedShort();
                    int type = readInt();
                    int specialSimpleName = readInt();
                    source[cindex] = enclosing.createProperty(attributes, ((TypeElement) constants[type]).getItem(), (String) constants[specialSimpleName], cindex, -1);
                    break;
                case CHUNK_TYPE:
                    enclosing = (ClassType) source[cindex];
                }
            }
            for(int sindex = 0; sindex < slengthOfLibrary; sindex++)
            {
                BinarySource source = (BinarySource) sourcesOfLibrary[sindex];
                Object[] constants = (Object[]) source[1];
                for(ChunkArray chunks = source.chunks, int clength = chunks.length - 1, int cindex = 2; cindex < clength; cindex++) with(chunks[cindex]) if(type == CHUNK_PROP)
                {
                    int indexMember = readInt();
                    int storedMember = readInt();
                    int readMember = readInt();
                    int writeMember = readInt();
                    Property property = (Property) source[cindex];
                    if(indexMember > 0) property.indexMember = ((TypedMemberElement) constants[indexMember]).getItem();
                    if(storedMember > 0) property.storedMember = ((TypedMemberElement) constants[storedMember]).getItem();
                    if(readMember > 0) property.readMember = ((TypedMemberElement) constants[readMember]).getItem();
                    if(writeMember > 0) property.writeMember = ((TypedMemberElement) constants[writeMember]).getItem();
                }
            }
            for(TableBuilderOperatorAndTypeHolder universalHolder = new TableBuilderOperatorAndTypeHolder(), int sindex = 0; sindex < slengthOfProject; sindex++)
            {
                TableBuilderTextSource source = (TableBuilderTextSource) sourcesOfProject[sindex];
                if(!isTypeSourceFileName(source.outputPath))
                {
                    continue;
                }
                for(ClassTypeArray declared = source.declared, int cindex = 0, int[][] tree = source.parsingTree, int tlength = tree.length, int tindex = 1; tindex < tlength; cindex++, tindex++)
                {
                    ClassType enclosing = declared[cindex];
                    if(enclosing.isStruct())
                    {
                        parseAllocatableMembers(source, tree[tindex][1], enclosing, enclosing);
                        continue;
                    }
                    for(int[] positions = tree[tindex], int plength = positions.length - 1, int pindex = 1; pindex < plength; pindex++)
                    {
                        int position = positions[pindex];
                        int kind = source.getLexemeKind(position);
                        /* документация */
                        int documentationPosition = -1;
                        if(kind == L_DOC)
                        {
                            documentationPosition = position++;
                            kind = source.getLexemeKind(position);
                        }
                        /* атрибуты */
                        int attributes;
                        /* видимость */
                        switch(kind)
                        {
                        default:
                            attributes = enclosing.isInterface() || enclosing.isHelper() ? PUBLIC : SOURCE;
                            break;
                        case PACKAGE:
                            if(enclosing.isHelper() && enclosing.getHelperForType().parentPackage != enclosing.parentPackage)
                            {
                                throw new TextSourceException(package.getResourceString("unsupported-visibility.helper-members")) { source = source, position = position };
                            }
                            /* падение через */
                        case PRIVATE:
                            if(enclosing.isInterface())
                            {
                                throw new TextSourceException(package.getResourceString("unsupported-visibility.interface-members")) { source = source, position = position };
                            }
                            /* падение через */
                        case PROTECTED:
                        case PUBLISHED:
                        case PUBLIC:
                            attributes = kind;
                            kind = source.getLexemeKind(++position);
                        }
                        /* связывание: static final, static, final, abstract */
                        int bindingPosition = position;
                        switch(kind)
                        {
                        case STATIC:
                            attributes |= ATTR_STATIC;
                            if((kind = source.getLexemeKind(++position)) == FINAL)
                            {
                                attributes |= ATTR_FINAL;
                                kind = source.getLexemeKind(++position);
                            }
                            else if(enclosing.isInterface())
                            {
                                attributes |= ATTR_FINAL;
                            }
                            break;
                        case FINAL:
                            attributes |= ATTR_FINAL;
                            if(enclosing.isService()) attributes |= ATTR_STATIC;
                            kind = source.getLexemeKind(++position);
                            break;
                        case ABSTRACT:
                            if(attributes <= PACKAGE && enclosing.isService())
                            {
                                throw new TextSourceException(package.getResourceString("unsupported-modifiers.abstract.hidden-members")) { source = source, position = position };
                            }
                            if(attributes <= PRIVATE && enclosing.isClass())
                            {
                                throw new TextSourceException(package.getResourceString("unsupported-modifiers.abstract.private-members")) { source = source, position = position };
                            }
                            if(enclosing.isHelper())
                            {
                                throw new TextSourceException(package.getResourceString("unsupported-modifiers.abstract.helper-members")) { source = source, position = position };
                            }
                            attributes |= ATTR_ABSTRACT;
                            kind = source.getLexemeKind(++position);
                        }
                        /* детали реализации: native interrupt, native, interrupt native, interrupt, synchronized */
                        int detailsPosition = position;
                        switch(kind)
                        {
                        case NATIVE:
                            if(enclosing.isInterface())
                            {
                                throw new TextSourceException(package.getResourceString("unsupported-implementation-details.interface-members")) { source = source, position = position };
                            }
                            if((attributes & ATTR_ABSTRACT) != 0)
                            {
                                throw new TextSourceException(package.getResourceString("unsupported-implementation-details.abstracts")) { source = source, position = position };
                            }
                            attributes |= ATTR_NATIVE;
                            if((kind = source.getLexemeKind(++position)) == INTERRUPT)
                            {
                                if((attributes & ATTR_STATIC) == 0)
                                {
                                    throw new TextSourceException(package.getResourceString("expected.static.interrupt")) { source = source, position = bindingPosition };
                                }
                                attributes |= ATTR_INTERRUPT;
                                kind = source.getLexemeKind(++position);
                            }
                            break;
                        case INTERRUPT:
                            if(enclosing.isInterface())
                            {
                                throw new TextSourceException(package.getResourceString("unsupported-implementation-details.interface-members")) { source = source, position = position };
                            }
                            if((attributes & ATTR_ABSTRACT) != 0)
                            {
                                throw new TextSourceException(package.getResourceString("unsupported-implementation-details.abstracts")) { source = source, position = position };
                            }
                            if((attributes & ATTR_STATIC) == 0)
                            {
                                throw new TextSourceException(package.getResourceString("expected.static.interrupt")) { source = source, position = bindingPosition };
                            }
                            attributes |= ATTR_INTERRUPT;
                            if((kind = source.getLexemeKind(++position)) == NATIVE)
                            {
                                attributes |= ATTR_NATIVE;
                                kind = source.getLexemeKind(++position);
                            }
                            break;
                        case SYNCHRONIZED:
                            if(enclosing.isInterface())
                            {
                                throw new TextSourceException(package.getResourceString("unsupported-implementation-details.interface-members")) { source = source, position = position };
                            }
                            if((attributes & ATTR_ABSTRACT) != 0)
                            {
                                throw new TextSourceException(package.getResourceString("unsupported-implementation-details.abstracts")) { source = source, position = position };
                            }
                            attributes |= ATTR_SYNCHRONIZED;
                            kind = source.getLexemeKind(++position);
                        }
                        /* члены типов */
                        switch(kind)
                        {
                        case CURLY_OPENED:
                            /* метод инициализации типа (статичный блок) */
                            if((attributes & ATTR_STATIC) == 0)
                            {
                                throw new TextSourceException(package.getResourceString("expected.static.static-block")) { source = source, position = bindingPosition };
                            }
                            if((attributes & (ATTR_NATIVE | ATTR_INTERRUPT | ATTR_SYNCHRONIZED)) != 0)
                            {
                                throw new TextSourceException(package.getResourceString("unsupported-implementation-details.static-blocks")) { source = source, position = detailsPosition };
                            }
                            if(enclosing.getStaticBlock() != null)
                            {
                                throw new TextSourceException(String.format(
                                    package.getResourceString("duplicate.static-block"), new Object[] { enclosing.specialSimpleName }
                                )) { source = source, position = position };
                            }
                            enclosing.createStaticBlock(attributes, position, documentationPosition).implementationPosition = position;
                            continue;
                        case PARENTH_OPENED:
                            /* метод инициализации объекта (конструктор) */
                            if(!enclosing.isClass())
                            {
                                throw new TextSourceException(package.getResourceString("can-be-used.constructors")) { source = source, position = position };
                            }
                            if((attributes & (ATTR_STATIC | ATTR_FINAL | ATTR_ABSTRACT)) != 0)
                            {
                                throw new TextSourceException(package.getResourceString("unsupported-modifiers.binding.constructors")) { source = source, position = bindingPosition };
                            }
                            if((attributes & (ATTR_NATIVE | ATTR_INTERRUPT | ATTR_SYNCHRONIZED)) != 0)
                            {
                                throw new TextSourceException(package.getResourceString("unsupported-implementation-details.constructors")) { source = source, position = detailsPosition };
                            }
                            int declarationPosition = position;
                            arguments.length = LIMIT_ARGUMENTS_LENGTH;
                            position = parseArgumentsClause(source, position + 1, enclosing, arguments);
                            if(enclosing.getChildCallable(SPECNAME_INST_INIT, arguments) != null)
                            {
                                throw new TextSourceException(String.format(
                                    package.getResourceString("duplicate.constructor"), new Object[] { enclosing.specialSimpleName }
                                )) { source = source, position = declarationPosition };
                            }
                            Method member = enclosing.createConstructor(attributes, arguments, declarationPosition, documentationPosition);
                            if(source.getLexemeKind(position) == THROWS) position = parseThrowsClause(source, position + 1, enclosing, member);
                            member.implementationPosition = position;
                            continue;
                        }
                        int returnTypePosition = position;
                        int declarationPosition = position = parseTypeName(source, position, enclosing, universalHolder);
                        Type returnTypeReference = universalHolder.resultType;
                        if((attributes & ATTR_INTERRUPT) != 0 && !returnTypeReference.isVoid())
                        {
                            throw new TextSourceException(package.getResourceString("type.required.interrupt")) { source = source, position = returnTypePosition };
                        }
                        switch(source.getLexemeKind(position))
                        {
                        default:
                            throw new TextSourceException(package.getResourceString("expected.name.member")) { source = source, position = position };
                        case OPERATOR:
                            /* оператор */
                            if((attributes & ATTR_STATIC) != 0)
                            {
                                throw new TextSourceException(package.getResourceString("unsupported-modifiers.static.operators")) { source = source, position = bindingPosition };
                            }
                            if(enclosing.isInterface()) attributes |= ATTR_ABSTRACT;
                            int argumentsPosition = position = parseOperator(source, position + 1, universalHolder);
                            kind = universalHolder.resultKind;
                            if(source.getLexemeKind(position) != PARENTH_OPENED)
                            {
                                throw new TextSourceException(package.getResourceString("expected.opened-parenth")) { source = source, position = position };
                            }
                            arguments.length = LIMIT_ARGUMENTS_LENGTH;
                            position = parseArgumentsClause(source, position + 1, enclosing, arguments);
                            int length = arguments.length;
                            if(length <= 0) switch(kind)
                            {
                            case O_SCAL_ADD:
                                kind = O_SCAL_POS;
                                break;
                            case O_SCAL_SUB:
                                kind = O_SCAL_NEG;
                                break;
                            case O_VECT_ADD:
                                kind = O_VECT_POS;
                                break;
                            case O_VECT_SUB:
                                kind = O_VECT_NEG;
                            }
                            switch(kind)
                            {
                            case WRITE_COMPONENT:
                                if(!returnTypeReference.isVoid())
                                {
                                    throw new TextSourceException(String.format(
                                        package.getResourceString("operator.return-void"), new Object[] { Operator.kindToSymbol(kind) }
                                    )) { source = source, position = returnTypePosition };
                                }
                                if(length != 2)
                                {
                                    throw new TextSourceException(String.format(
                                        package.getResourceString("operator.arguments.2"), new Object[] { Operator.kindToSymbol(kind) }
                                    )) { source = source, position = argumentsPosition };
                                }
                                break;
                            case READ_COMPONENT:
                                if(returnTypeReference.isVoid())
                                {
                                    throw new TextSourceException(String.format(
                                        package.getResourceString("operator.return-type"), new Object[] { Operator.kindToSymbol(kind) }
                                    )) { source = source, position = returnTypePosition };
                                }
                                if(length != 1)
                                {
                                    throw new TextSourceException(String.format(
                                        package.getResourceString("operator.arguments.1"), new Object[] { Operator.kindToSymbol(kind) }
                                    )) { source = source, position = argumentsPosition };
                                }
                                break;
                            case O_SCAL_GT:
                            case O_SCAL_GE:
                            case O_SCAL_LT:
                            case O_SCAL_LE:
                            case R_SCAL_GT:
                            case R_SCAL_GE:
                            case R_SCAL_LT:
                            case R_SCAL_LE:
                                if(!returnTypeReference.isBoolean())
                                {
                                    throw new TextSourceException(String.format(
                                        package.getResourceString("operator.return-boolean"), new Object[] { Operator.kindToSymbol(kind) }
                                    )) { source = source, position = returnTypePosition };
                                }
                                if(length != 1)
                                {
                                    throw new TextSourceException(String.format(
                                        package.getResourceString("operator.arguments.1"), new Object[] { Operator.kindToSymbol(kind) }
                                    )) { source = source, position = argumentsPosition };
                                }
                                break;
                            case O_BIT_AND:
                            case O_BIT_OR:
                            case O_BIT_XOR:
                            case O_SCAL_MUL:
                            case O_SCAL_DIV:
                            case O_SCAL_DIVU:
                            case O_SCAL_REM:
                            case O_SCAL_REMU:
                            case O_SCAL_ADD:
                            case O_SCAL_SUB:
                            case O_SCAL_SHR:
                            case O_SCAL_SHRU:
                            case O_SCAL_SHL:
                            case O_VECT_MUL:
                            case O_VECT_DIV:
                            case O_VECT_ADD:
                            case O_VECT_SUB:
                            case O_VECT_SHR:
                            case O_VECT_SHRU:
                            case O_VECT_SHL:
                            case O_VECT_GT:
                            case O_VECT_GE:
                            case O_VECT_LT:
                            case O_VECT_LE:
                            case O_VECT_EQ:
                            case O_VECT_NE:
                            case O_VECT_HMUL:
                            case O_VECT_SADD:
                            case O_VECT_SSUB:
                            case O_VECT_HMULU:
                            case O_VECT_SADDU:
                            case O_VECT_SSUBU:
                            case R_BIT_AND:
                            case R_BIT_OR:
                            case R_BIT_XOR:
                            case R_SCAL_MUL:
                            case R_SCAL_DIV:
                            case R_SCAL_DIVU:
                            case R_SCAL_REM:
                            case R_SCAL_REMU:
                            case R_SCAL_ADD:
                            case R_SCAL_SUB:
                            case R_SCAL_SHR:
                            case R_SCAL_SHRU:
                            case R_SCAL_SHL:
                            case R_VECT_MUL:
                            case R_VECT_DIV:
                            case R_VECT_ADD:
                            case R_VECT_SUB:
                            case R_VECT_SHR:
                            case R_VECT_SHRU:
                            case R_VECT_SHL:
                            case R_VECT_GT:
                            case R_VECT_GE:
                            case R_VECT_LT:
                            case R_VECT_LE:
                            case R_VECT_EQ:
                            case R_VECT_NE:
                            case R_VECT_HMUL:
                            case R_VECT_SADD:
                            case R_VECT_SSUB:
                            case R_VECT_HMULU:
                            case R_VECT_SADDU:
                            case R_VECT_SSUBU:
                                if(returnTypeReference.isVoid())
                                {
                                    throw new TextSourceException(String.format(
                                        package.getResourceString("operator.return-type"), new Object[] { Operator.kindToSymbol(kind) }
                                    )) { source = source, position = returnTypePosition };
                                }
                                if(length != 1)
                                {
                                    throw new TextSourceException(String.format(
                                        package.getResourceString("operator.arguments.1"), new Object[] { Operator.kindToSymbol(kind) }
                                    )) { source = source, position = argumentsPosition };
                                }
                                break;
                            case O_BIT_NOT:
                            case O_SCAL_POS:
                            case O_SCAL_NEG:
                            case O_VECT_POS:
                            case O_VECT_NEG:
                            case O_VECT_LUP:
                            case O_VECT_UUP:
                            case O_VECT_PCK:
                                if(returnTypeReference.isVoid())
                                {
                                    throw new TextSourceException(String.format(
                                        package.getResourceString("operator.return-type"), new Object[] { Operator.kindToSymbol(kind) }
                                    )) { source = source, position = returnTypePosition };
                                }
                                if(length > 0)
                                {
                                    throw new TextSourceException(String.format(
                                        package.getResourceString("operator.arguments.0"), new Object[] { Operator.kindToSymbol(kind) }
                                    )) { source = source, position = argumentsPosition };
                                }
                            }
                            if(enclosing.getChildCallable(Operator.kindToSpecialSimpleName(kind), arguments) != null)
                            {
                                throw new TextSourceException(String.format(
                                    package.getResourceString("duplicate.operator"), new Object[] { enclosing.specialSimpleName, Operator.kindToSymbol(kind) }
                                )) { source = source, position = declarationPosition };
                            }
                            enclosing.createOperator(attributes, returnTypeReference, kind, arguments, declarationPosition, documentationPosition).implementationPosition = position;
                            continue;
                        case L_NAME:
                        }
                        String specialSimpleName = source.getLexemeString(position);
                        switch(source.getLexemeKind(++position))
                        {
                        case PARENTH_OPENED:
                            /* метод */
                            if(enclosing.isInterface())
                            {
                                if((attributes & (ATTR_STATIC | ATTR_FINAL)) != 0)
                                {
                                    throw new TextSourceException(package.getResourceString("unsupported-modifiers.static-final.interface-methods")) { source = source, position = bindingPosition };
                                }
                                attributes |= ATTR_ABSTRACT;
                            }
                            Member found = enclosing.getChildMember(specialSimpleName);
                            if(found != null && (attributes & ATTR_INTERRUPT) != 0)
                            {
                                throw new TextSourceException(String.format(
                                    package.getResourceString("duplicate.interrupt"), new Object[] { enclosing.specialSimpleName, specialSimpleName }
                                )) { source = source, position = declarationPosition };
                            }
                            if(found instanceof Fieldoid)
                            {
                                throw new TextSourceException(String.format(
                                    package.getResourceString("duplicate.member.fieldoid"), new Object[] { enclosing.specialSimpleName, specialSimpleName }
                                )) { source = source, position = declarationPosition };
                            }
                            arguments.length = LIMIT_ARGUMENTS_LENGTH;
                            position = parseArgumentsClause(source, position + 1, enclosing, arguments);
                            if(enclosing.getChildCallable(specialSimpleName, arguments) != null)
                            {
                                throw new TextSourceException(String.format(
                                    package.getResourceString("duplicate.method"), new Object[] { enclosing.specialSimpleName, specialSimpleName }
                                )) { source = source, position = declarationPosition };
                            }
                            Method member = enclosing.createMethod(attributes, returnTypeReference, specialSimpleName, arguments, declarationPosition, documentationPosition);
                            if(source.getLexemeKind(position) == THROWS)
                            {
                                if((attributes & ATTR_INTERRUPT) != 0)
                                {
                                    throw new TextSourceException(package.getResourceString("unsupported-throws.interrupt")) { source = source, position = position };
                                }
                                position = parseThrowsClause(source, position + 1, enclosing, member);
                            }
                            member.implementationPosition = position;
                            break;
                        case CURLY_OPENED:
                            /* свойство */
                            if((attributes & ATTR_STATIC) != 0)
                            {
                                throw new TextSourceException(package.getResourceString("unsupported-modifiers.static.properties")) { source = source, position = bindingPosition };
                            }
                            if((attributes & (ATTR_NATIVE | ATTR_INTERRUPT | ATTR_SYNCHRONIZED)) != 0)
                            {
                                throw new TextSourceException(package.getResourceString("unsupported-implementation-details.properties")) { source = source, position = detailsPosition };
                            }
                            if(returnTypeReference.isVoid())
                            {
                                throw new TextSourceException(String.format(
                                    package.getResourceString("type.not-suitable.property"), new Object[] { returnTypeReference }
                                )) { source = source, position = returnTypePosition };
                            }
                            if(enclosing.getChildMember(specialSimpleName) != null)
                            {
                                throw new TextSourceException(String.format(
                                    package.getResourceString("duplicate.member"), new Object[] { enclosing.specialSimpleName, specialSimpleName }
                                )) { source = source, position = declarationPosition };
                            }
                            if(enclosing.isInterface()) attributes |= ATTR_ABSTRACT;
                            Property member = enclosing.createProperty(attributes, returnTypeReference, specialSimpleName, declarationPosition, documentationPosition);
                            int implementationPosition = member.implementationPosition = position;
                            boolean isAbstract = (attributes & ATTR_ABSTRACT) != 0;
                            boolean hasWrite = false;
                            boolean hasRead = false;
                            attributes |= ATTR_SYNTHETIC;
                            kind = source.getLexemeKind(++position);
                            label0:
                            {
                                /* index */
                                if(kind == L_NAME && MEMBER_SUFFIX_INDEX.equals(source.getLexemeString(position)))
                                {
                                    if(isAbstract)
                                    {
                                        throw new TextSourceException(package.getResourceString("unsupported-specifiers.index")) { source = source, position = position };
                                    }
                                    if(source.getLexemeKind(++position) != EQUALS)
                                    {
                                        throw new TextSourceException(package.getResourceString("expected.equals")) { source = source, position = position };
                                    }
                                    enclosing.createMethod(attributes, typeInt, specialSimpleName + ("." + MEMBER_SUFFIX_INDEX), null, -1, -1).implementationPosition = ++position;
                                    if((kind = source.getLexemeKind(position = skipPropertySpecifier(source, position))) != COMMA) break label0;
                                    kind = source.getLexemeKind(++position);
                                }
                                /* read */
                                if(kind == L_NAME && MEMBER_SUFFIX_READ.equals(source.getLexemeString(position)))
                                {
                                    hasRead = true;
                                    if(isAbstract)
                                    {
                                        enclosing.createMethod(attributes, returnTypeReference, specialSimpleName + ("." + MEMBER_SUFFIX_READ), null, -1, -1);
                                        if((kind = source.getLexemeKind(++position)) != COMMA) break label0;
                                    } else
                                    {
                                        if(source.getLexemeKind(++position) != EQUALS)
                                        {
                                            throw new TextSourceException(package.getResourceString("expected.equals")) { source = source, position = position };
                                        }
                                        enclosing.createMethod(attributes, returnTypeReference, specialSimpleName + ("." + MEMBER_SUFFIX_READ), null, -1, -1).implementationPosition = ++position;
                                        if((kind = source.getLexemeKind(position = skipPropertySpecifier(source, position))) != COMMA) break label0;
                                    }
                                    kind = source.getLexemeKind(++position);
                                }
                                /* write */
                                if(kind == L_NAME && MEMBER_SUFFIX_WRITE.equals(source.getLexemeString(position)))
                                {
                                    hasWrite = true;
                                    arguments.length = 1;
                                    arguments[0] = createLocal(true, returnTypeReference, SPECNAME_VALUE, null, source, declarationPosition);
                                    if(isAbstract)
                                    {
                                        enclosing.createMethod(attributes, typeVoid, specialSimpleName + ("." + MEMBER_SUFFIX_WRITE), arguments, -1, -1);
                                        if((kind = source.getLexemeKind(++position)) != COMMA) break label0;
                                    } else
                                    {
                                        if(source.getLexemeKind(++position) != EQUALS)
                                        {
                                            throw new TextSourceException(package.getResourceString("expected.equals")) { source = source, position = position };
                                        }
                                        enclosing.createMethod(attributes, typeVoid, specialSimpleName + ("." + MEMBER_SUFFIX_WRITE), arguments, -1, -1).implementationPosition = ++position;
                                        if((kind = source.getLexemeKind(position = skipPropertySpecifier(source, position))) != COMMA) break label0;
                                    }
                                    kind = source.getLexemeKind(++position);
                                }
                                /* stored */
                                if(kind == L_NAME && MEMBER_SUFFIX_STORED.equals(source.getLexemeString(position)))
                                {
                                    if(isAbstract)
                                    {
                                        throw new TextSourceException(package.getResourceString("unsupported-specifiers.stored")) { source = source, position = position };
                                    }
                                    if(source.getLexemeKind(++position) != EQUALS)
                                    {
                                        throw new TextSourceException(package.getResourceString("expected.equals")) { source = source, position = position };
                                    }
                                    enclosing.createMethod(attributes, typeBoolean, specialSimpleName + ("." + MEMBER_SUFFIX_STORED), null, -1, -1).implementationPosition = ++position;
                                    kind = source.getLexemeKind(position = skipPropertySpecifier(source, position));
                                }
                            }
                            if(kind != CURLY_CLOSED)
                            {
                                throw new TextSourceException(package.getResourceString("expected.closed-curly")) { source = source, position = position };
                            }
                            if(!hasRead && !hasWrite)
                            {
                                throw new TextSourceException(package.getResourceString("expected.property-specifier.read-or-write")) { source = source, position = implementationPosition };
                            }
                            break;
                        default:
                            /* поле */
                            if((attributes & ATTR_ABSTRACT) != 0)
                            {
                                throw new TextSourceException(package.getResourceString("unsupported-modifiers.abstract.fields")) { source = source, position = bindingPosition };
                            }
                            if((attributes & (ATTR_NATIVE | ATTR_INTERRUPT | ATTR_SYNCHRONIZED)) != 0)
                            {
                                throw new TextSourceException(package.getResourceString("unsupported-implementation-details.fields")) { source = source, position = detailsPosition };
                            }
                            if(returnTypeReference.isVoid())
                            {
                                throw new TextSourceException(String.format(
                                    package.getResourceString("type.not-suitable.field"), new Object[] { returnTypeReference }
                                )) { source = source, position = returnTypePosition };
                            }
                            if(enclosing.getChildMember(specialSimpleName) != null)
                            {
                                throw new TextSourceException(String.format(
                                    package.getResourceString("duplicate.member"), new Object[] { enclosing.specialSimpleName, specialSimpleName }
                                )) { source = source, position = declarationPosition };
                            }
                            if(enclosing.isService()) attributes |= enclosing.isInterface() ? ATTR_STATIC | ATTR_FINAL : ATTR_STATIC;
                            enclosing.createClassField(attributes, returnTypeReference, specialSimpleName, declarationPosition, documentationPosition).implementationPosition = position;
                        }
                    }
                }
            }
            createMembersForArrayTypes();
            appendImpliedMembers(classes);
            appendImpliedMembers(arrays);
            checkMembers(classes);
            checkMembers(arrays);
        }
    }

    public Library createLibrary(FileSystem fileSystem, String directoryPath, boolean application) { return fldProject = super.createLibrary(fileSystem, directoryPath, application); }

    public final boolean documentationEnabled { read = fldLanguageLexer.documentationEnabled, write = fldLanguageLexer.documentationEnabled = value }

    public final DocumentLexer documentationLexer { read = fldDocumentationLexer }

    public final LanguageLexer languageLexer { read = fldLanguageLexer }

    public final Library project { read = fldProject }

    protected void afterConstruction() {
        super.afterConstruction();
        DocumentLexer documentationLexer = createDocumentLexer();
        if(documentationLexer == null) documentationLexer = new DocumentLexer();
        fldDocumentationLexer = documentationLexer;
        LanguageLexer languageLexer = createLanguageLexer(documentationLexer);
        if(languageLexer == null) languageLexer = new LanguageLexer(documentationLexer);
        fldLanguageLexer = languageLexer;
    }

    protected void prefetchSupertypesForPrimitiveArray(ArrayType array) {
        String name = array.componentType.specialSimpleName;
        name = (new StringBuilder() + Char.toUpperCase(name[0]) + name.substring(1) + "Array").toString();
        String[] names = new String[] {
            PACKNAME_LANG + "." + TYPENAME_RAW_DATA,
            PACKNAME_LANG + "." + TYPENAME_CLONEABLE,
            PACKNAME_ARRAY + "." + TYPENAME_MEASUREABLE,
            PACKNAME_ARRAY + "." + TYPENAME_MUTABLE_MEASUREABLE,
            PACKNAME_ARRAY + ".Resizeable" + name,
            PACKNAME_ARRAY + ".Mutable" + name,
            PACKNAME_ARRAY + "." + name
        };
        for(array.initSuperclass(getClassType(PACKNAME_LANG + "." + TYPENAME_OBJECT), -1), int length = names.length, int index = 0; index < length; index++)
        {
            ClassType supertypeReference = getClassType(names[index]);
            if(supertypeReference != null && (supertypeReference.attributes & (PUBLIC | ATTR_SERVICE)) == (PUBLIC | ATTR_SERVICE)) array.appendSuperservice(supertypeReference, -1);
        }
    }

    protected void prefetchSupertypesForObjectArray(ArrayType array) {
        String name = array.componentType.specialSimpleName;
        name = (new StringBuilder() + Char.toUpperCase(name[0]) + name.substring(1) + "Array").toString();
        String[] names = new String[] {
            PACKNAME_LANG + "." + TYPENAME_IMMUTABLE_OBJECT,
            PACKNAME_LANG + "." + TYPENAME_CLONEABLE,
            PACKNAME_ARRAY + "." + TYPENAME_MEASUREABLE,
            PACKNAME_ARRAY + "." + TYPENAME_MUTABLE_MEASUREABLE,
            PACKNAME_ARRAY + "." + TYPENAME_IMMUTABLE_MEASUREABLE,
            PACKNAME_ARRAY + ".Resizeable" + name,
            PACKNAME_ARRAY + ".Immutable" + name,
            PACKNAME_ARRAY + ".Mutable" + name,
            PACKNAME_ARRAY + "." + name
        };
        for(array.initSuperclass(getClassType(PACKNAME_LANG + "." + TYPENAME_OBJECT), -1), int length = names.length, int index = 0; index < length; index++)
        {
            ClassType supertypeReference = getClassType(names[index]);
            if(supertypeReference != null && (supertypeReference.attributes & (PUBLIC | ATTR_SERVICE)) == (PUBLIC | ATTR_SERVICE)) array.appendSuperservice(supertypeReference, -1);
        }
    }

    protected void prefetchSupertypesForReferenceArray(ArrayType array) { array.initSuperclass(getClassType(PACKNAME_LANG + "." + TYPENAME_OBJECT + "[]"), -1); }

    protected void createMembersForPrimitiveArray(ArrayType array) {
        boolean is64bits = pointerSize == BITS64;
        Type classStruct = getType(PACKNAME_LANG + "." + TYPENAME_STRUCT);
        Type componentType = array.componentType;
        Type typeVoid = getPrimitiveType(VOID);
        Type typeLong = getPrimitiveType(LONG);
        Type typeInt = getPrimitiveType(INT);
        TypedMember fieldLength = array.createClassField(PRIVATE, typeInt, "fldLength", -1, -1);
        if(is64bits) array.createClassField(PRIVATE, typeInt, "fldLengthZeroContinuation", -1, -1);
        TypedMember fieldCapacity = array.createClassField(PRIVATE, typeInt, "fldCapacity", -1, -1);
        if(is64bits) array.createClassField(PRIVATE, typeInt, "fldCapacityZeroContinuation", -1, -1);
        array.createClassField(PRIVATE, classStruct, "fldParentStruct", -1, -1);
        array.createClassField(PRIVATE, is64bits ? typeLong : typeInt, "fldOffset", -1, -1);
        if(componentType.isChar()) array.createMethod(PUBLIC | ATTR_NATIVE, getType(PACKNAME_LANG + "." + TYPENAME_STRING), "toString", null, -1, -1);
        array.createMethod(PUBLIC | ATTR_NATIVE, typeLong, "getPointer", null, -1, -1);
        array.createMethod(PUBLIC | ATTR_NATIVE, typeLong, "getLength", null, -1, -1);
        array.createMethod(PUBLIC | ATTR_NATIVE, array, "clone", null, -1, -1);
        Property propertyLength = array.createProperty(PUBLIC, typeInt, "length", -1, -1);
        Property propertyCapacity = array.createProperty(PUBLIC, typeInt, "capacity", -1, -1);
        array.createOperator(PUBLIC | ATTR_NATIVE, typeVoid, WRITE_COMPONENT, new Local[] {
            createLocal(false, typeInt, "index", null, null, -1),
            createLocal(false, componentType, "component", null, null, -1)
        }, -1, -1);
        array.createOperator(PUBLIC | ATTR_NATIVE, componentType, READ_COMPONENT, new Local[] {
            createLocal(false, typeInt, "index", null, null, -1)
        }, -1, -1);
        TypedMember methodSetLength = array.createMethod(PRIVATE | ATTR_NATIVE, typeVoid, "setLength", new Local[] {
            createLocal(false, typeInt, "newLength", null, null, -1)
        }, -1, -1);
        array.createMethod(PUBLIC | ATTR_SYNTHETIC, typeInt, propertyLength.specialSimpleName + ("." + MEMBER_SUFFIX_READ), null, -1, -1);
        array.createMethod(PUBLIC | ATTR_SYNTHETIC, typeVoid, propertyLength.specialSimpleName + ("." + MEMBER_SUFFIX_WRITE), new Local[] {
            createLocal(false, typeInt, SPECNAME_VALUE, null, null, -1)
        }, -1, -1);
        array.createMethod(PUBLIC | ATTR_SYNTHETIC, typeInt, propertyCapacity.specialSimpleName + ("." + MEMBER_SUFFIX_READ), null, -1, -1);
        propertyLength.readMember = fieldLength;
        propertyLength.writeMember = methodSetLength;
        propertyCapacity.readMember = fieldCapacity;
    }

    protected void createMembersForObjectArray(ArrayType array) {
        boolean is64bits = pointerSize == BITS64;
        Type componentType = array.componentType;
        Type typeVoid = getPrimitiveType(VOID);
        Type typeLong = getPrimitiveType(LONG);
        Type typeInt = getPrimitiveType(INT);
        TypedMember fieldLength = array.createClassField(PRIVATE, typeInt, "fldLength", -1, -1);
        if(is64bits) array.createClassField(PRIVATE, typeInt, "fldLengthZeroContinuation", -1, -1);
        array.createClassField(PRIVATE, typeInt, "fldCapacity", -1, -1);
        if(is64bits) array.createClassField(PRIVATE, typeInt, "fldCapacityZeroContinuation", -1, -1);
        array.createClassField(PRIVATE, is64bits ? typeLong : typeInt, "fldReserved30", -1, -1);
        array.createClassField(PRIVATE, is64bits ? typeLong : typeInt, "fldOffset", -1, -1);
        array.createMethod(PUBLIC | ATTR_NATIVE, typeVoid, "finalize", null, -1, -1);
        array.createMethod(PUBLIC | ATTR_NATIVE, getPrimitiveType(BOOLEAN), "isMutable", null, -1, -1);
        array.createMethod(PUBLIC | ATTR_NATIVE, array, "clone", null, -1, -1);
        Property propertyLength = array.createProperty(PUBLIC, typeInt, "length", -1, -1);
        Property propertyCapacity = array.createProperty(PUBLIC, typeInt, "capacity", -1, -1);
        array.createOperator(PUBLIC | ATTR_NATIVE, typeVoid, WRITE_COMPONENT, new Local[] {
            createLocal(false, typeInt, "index", null, null, -1),
            createLocal(false, componentType, "component", null, null, -1)
        }, -1, -1);
        array.createOperator(PUBLIC | ATTR_NATIVE, componentType, READ_COMPONENT, new Local[] {
            createLocal(false, typeInt, "index", null, null, -1)
        }, -1, -1);
        TypedMember methodSetLength = array.createMethod(PRIVATE | ATTR_NATIVE, typeVoid, "setLength", new Local[] {
            createLocal(false, typeInt, "newLength", null, null, -1)
        }, -1, -1);
        TypedMember methodGetCapacity = array.createMethod(PRIVATE | ATTR_NATIVE, typeInt, "getCapacity", null, -1, -1);
        array.createMethod(PUBLIC | ATTR_SYNTHETIC, typeInt, propertyLength.specialSimpleName + ("." + MEMBER_SUFFIX_READ), null, -1, -1);
        array.createMethod(PUBLIC | ATTR_SYNTHETIC, typeVoid, propertyLength.specialSimpleName + ("." + MEMBER_SUFFIX_WRITE), new Local[] {
            createLocal(false, typeInt, SPECNAME_VALUE, null, null, -1)
        }, -1, -1);
        array.createMethod(PUBLIC | ATTR_SYNTHETIC, typeInt, propertyCapacity.specialSimpleName + ("." + MEMBER_SUFFIX_READ), null, -1, -1);
        propertyLength.readMember = fieldLength;
        propertyLength.writeMember = methodSetLength;
        propertyCapacity.readMember = methodGetCapacity;
    }

    protected DocumentLexer createDocumentLexer() { return null; }

    protected LanguageLexer createLanguageLexer(DocumentLexer documentationLexer) { return null; }

    protected final Source newSource(Library parentLibrary, String relativePath, String type) {
        return !TEXT_SOURCE.equals(type) ? super.newSource(parentLibrary, relativePath, type) : new TableBuilderTextSource(parentLibrary, relativePath);
    }

    protected final String getSourceType(Library library) { return library == fldProject ? TEXT_SOURCE : BINARY_SOURCE; }

    package final int parsePackageName(TextSource source, int position, StringBuilder specialCanonicalName) throws TextSourceException {
        if(source.getLexemeKind(position) != L_NAME)
        {
            throw new TextSourceException(package.getResourceString("expected.name.package")) { source = source, position = position };
        }
        specialCanonicalName + source.getLexemeString(position);
        while(source.getLexemeKind(++position) == PERIOD)
        {
            if(source.getLexemeKind(++position) != L_NAME)
            {
                throw new TextSourceException(package.getResourceString("expected.continue.package")) { source = source, position = position };
            }
            specialCanonicalName + '.' + source.getLexemeString(position);
        }
        return position;
    }

    package final int parseClassName(TextSource source, int position, ClassType enclosing, TypeHolder parsed) throws TextSourceException {
        if(source.getLexemeKind(position) != L_NAME)
        {
            throw new TextSourceException(package.getResourceString("expected.name.package-or-type")) { source = source, position = position };
        }
        ClassType result;
        label0:
        {
            int start = position;
            String name = source.getLexemeString(position++);
            /* поиск среди типов в исходном коде */
            if((result = source.getDeclaredType(name)) != null) break label0;
            if((result = source.getImportedType(name)) != null) break label0;
            /* поиск в родительском пакете */
            if((result = (ClassType) source.owner.getChildType(name)) != null && result.isVisibleFrom(enclosing)) break label0;
            /* поиск среди неявно импортированных типов */
            ClassType[] types = source.findImplicitlyImportedTypes(name, enclosing);
            int length = types.length;
            if(length > 0 && (result = types[0]).isVisibleFrom(enclosing))
            {
                if(length > 1)
                {
                    throw new TextSourceException(String.format(package.getResourceString("ambiguous.type"), new Object[] { name })) { source = source, position = start };
                }
                break label0;
            }
            /* поиск в языковом пакете */
            if((result = (ClassType) getLanguagePackage().getChildType(name)) != null && result.isVisibleFrom(enclosing)) break label0;
            /* распознавание канонического имени типа */
            StringBuilder specialCanonicalName = new StringBuilder(LIMIT_NAME_LENGTH) + name;
            while(source.getLexemeKind(position) == PERIOD)
            {
                if(source.getLexemeKind(++position) != L_NAME)
                {
                    throw new TextSourceException(package.getResourceString("expected.name.package-or-type")) { source = source, position = position };
                }
                if((result = getClassType(name = (specialCanonicalName + '.' + source.getLexemeString(position++)).toString())) != null)
                {
                    if(!result.isVisibleFrom(enclosing))
                    {
                        throw new TextSourceException(String.format(package.getResourceString("invisible.type"), new Object[] { name })) { source = source, position = start };
                    }
                    break label0;
                }
            }
            /* не найдено? */
            throw new TextSourceException(String.format(package.getResourceString("not-found.type"), new Object[] { specialCanonicalName })) { source = source, position = start };
        }
        if(!parsed.helpersAllowed && result.isHelper())
        {
            throw new TextSourceException(String.format(package.getResourceString("helper.reference"), new Object[] { result.specialCanonicalName })) { source = source, position = position };
        }
        parsed.resultType = result;
        return position;
    }

    package final int parseTypeName(TextSource source, int position, ClassType enclosing, TypeHolder parsed) throws TextSourceException {
        int kind = source.getLexemeKind(position);
        if(kind == VOID)
        {
            parsed.resultType = getPrimitiveType(VOID);
            return position + 1;
        }
        Type result;
        if(kind > VOID && kind < VOID + PRIMITIVES_LENGTH && isPrimitiveKind(kind))
        {
            position++;
            result = getPrimitiveType(kind);
        } else
        {
            position = parseClassName(source, position, enclosing, parsed);
            if((result = parsed.resultType).isHelper())
            {
                parsed.resultType = result;
                return position;
            }
        }
        for(int dimCount = 0; dimCount < LIMIT_DIMENSIONS_COUNT && source.getLexemeKind(position) == BRACKET_OPENED && source.getLexemeKind(position + 1) == BRACKET_CLOSED; position += 2, dimCount++)
        {
            result = acquireArrayType(result);
        }
        parsed.resultType = result;
        return position;
    }

    package final int parseOperator(TextSource source, int position, OperatorHolder parsed) throws TextSourceException {
        int result = source.getLexemeKind(position);
        switch(result)
        {
        default:
            throw new TextSourceException(package.getResourceString("expected.valid-operator")) { source = source, position = position };
        case BRACKET_OPENED:
            if(source.getLexemeKind(++position) != BRACKET_CLOSED)
            {
                throw new TextSourceException(package.getResourceString("expected.closed-bracket")) { source = source, position = position };
            }
            if(source.getLexemeKind(++position) != EQUALS)
            {
                result = READ_COMPONENT;
                break;
            }
            result = WRITE_COMPONENT;
            position++;
            break;
        case PARENTH_OPENED:
            if(source.getLexemeKind(++position) != PARENTH_CLOSED)
            {
                throw new TextSourceException(package.getResourceString("expected.closed-parenth")) { source = source, position = position };
            }
            result = INVOKE_VIRTUAL;
            position++;
            break;
        case O_BIT_AND:
        case O_BIT_OR:
        case O_BIT_XOR:
        case O_SCAL_MUL:
        case O_SCAL_DIV:
        case O_SCAL_DIVU:
        case O_SCAL_REM:
        case O_SCAL_REMU:
        case O_SCAL_ADD:
        case O_SCAL_SUB:
        case O_SCAL_SHR:
        case O_SCAL_SHRU:
        case O_SCAL_SHL:
        case O_SCAL_GT:
        case O_SCAL_GE:
        case O_SCAL_LT:
        case O_SCAL_LE:
        case O_VECT_MUL:
        case O_VECT_DIV:
        case O_VECT_ADD:
        case O_VECT_SUB:
        case O_VECT_SHR:
        case O_VECT_SHRU:
        case O_VECT_SHL:
        case O_VECT_GT:
        case O_VECT_GE:
        case O_VECT_LT:
        case O_VECT_LE:
        case O_VECT_EQ:
        case O_VECT_NE:
        case O_VECT_HMUL:
        case O_VECT_SADD:
        case O_VECT_SSUB:
        case O_VECT_HMULU:
        case O_VECT_SADDU:
        case O_VECT_SSUBU:
            if(source.getLexemeKind(++position) != REVERSE) break;
            result += R_DELTA;
            /* падение через */
        case O_BIT_NOT:
        case O_SCAL_POS:
        case O_SCAL_NEG:
        case O_VECT_POS:
        case O_VECT_NEG:
        case O_VECT_LUP:
        case O_VECT_UUP:
        case O_VECT_PCK:
            position++;
        }
        parsed.resultKind = result;
        return position;
    }

    private int parseAllocatableMembers(TextSource source, int position, ClassType enclosing, AllocatableFactory container) throws TextSourceException {
        for(int kind; (kind = source.getLexemeKind(position)) != CURLY_CLOSED; position++)
        {
            /* документация */
            int documentationPosition = -1;
            if(kind == L_DOC)
            {
                documentationPosition = position++;
                kind = source.getLexemeKind(position);
            }
            switch(kind)
            {
            /* вложенная структура */
            case STRUCT:
                int declarationPosition = position;
                if(source.getLexemeKind(++position) != CURLY_OPENED)
                {
                    throw new TextSourceException(package.getResourceString("expected.opened-curly")) { source = source, position = position };
                }
                position = parseAllocatableMembers(source, position + 1, enclosing, container.createNestedStruct(declarationPosition, documentationPosition));
                continue;
            /* вложенное объединение */
            case UNION:
                int declarationPosition = position;
                if(source.getLexemeKind(++position) != CURLY_OPENED)
                {
                    throw new TextSourceException(package.getResourceString("expected.opened-curly")) { source = source, position = position };
                }
                position = parseAllocatableMembers(source, position + 1, enclosing, container.createNestedUnion(declarationPosition, documentationPosition));
                continue;
            /* видимость */
            case PRIVATE:
            case PACKAGE:
            case PROTECTED:
                throw new TextSourceException(package.getResourceString("unsupported-visibility.struct-field")) { source = source, position = position };
            case PUBLIC:
            case PUBLISHED:
                kind = source.getLexemeKind(++position);
            }
            /* тип */
            if(kind < VOID || kind >= VOID + PRIMITIVES_LENGTH || !isPrimitiveKind(kind))
            {
                throw new TextSourceException(package.getResourceString("expected.primitive-type")) { source = source, position = position };
            }
            Type type = getPrimitiveType(kind);
            if(type.isVoid())
            {
                throw new TextSourceException(String.format(
                    package.getResourceString("type.not-suitable.field"), new Object[] { type }
                )) { source = source, position = position };
            }
            /* ёмкость */
            int capacity = 0;
            if((kind = source.getLexemeKind(++position)) == BRACKET_OPENED)
            {
                if((kind = source.getLexemeKind(++position)) != L_BYTE && kind != L_SHORT && kind != L_INT)
                {
                    throw new TextSourceException(package.getResourceString("expected.number-of-int")) { source = source, position = position };
                }
                if((capacity = source.getLexemeInt(position)) < 1 || capacity > LIMIT_FIELD_LENGTH)
                {
                    throw new TextSourceException(String.format(
                        package.getResourceString("struct-field.capacity"), new Object[] { Int.toString(LIMIT_FIELD_LENGTH) }
                    )) { source = source, position = position };
                }
                if(source.getLexemeKind(++position) != BRACKET_CLOSED)
                {
                    throw new TextSourceException(package.getResourceString("expected.closed-bracket")) { source = source, position = position };
                }
                type = getArrayType(type);
                kind = source.getLexemeKind(++position);
            }
            /* название */
            String specialSimpleName = null;
            int declarationPosition = -1;
            if(kind == L_NAME)
            {
                if(enclosing.getChildMember(specialSimpleName = source.getLexemeString(position)) != null)
                {
                    throw new TextSourceException(String.format(package.getResourceString("duplicate.name.field"), new Object[] { specialSimpleName })) { source = source, position = position };
                }
                declarationPosition = position++;
                kind = source.getLexemeKind(position);
            }
            /* обязательная точка с запятой */
            if(kind != SEMICOLON)
            {
                throw new TextSourceException(package.getResourceString("expected.semicolon")) { source = source, position = position };
            }
            /* создание поля */
            container.createStructField(type, capacity, specialSimpleName, declarationPosition, documentationPosition);
        }
        return position;
    }

    private int parseArgumentsClause(TextSource source, int position, ClassType enclosing, Local[] arguments) throws TextSourceException {
        label0: if(source.getLexemeKind(position) == PARENTH_CLOSED)
        {
            arguments.length = 0;
            position++;
        } else
        {
            for(int length = arguments.length, TableBuilderVectorAndTypeHolder universalHolder = new TableBuilderVectorAndTypeHolder(length), int index = 0; index < length; )
            {
                boolean isFinal = false;
                if(source.getLexemeKind(position) == FINAL)
                {
                    isFinal = true;
                    position++;
                }
                int before = position;
                position = parseTypeName(source, position, enclosing, universalHolder);
                Type argumentType = universalHolder.resultType;
                if(argumentType.isVoid())
                {
                    throw new TextSourceException(String.format(
                        package.getResourceString("type.not-suitable.argument"), new Object[] { argumentType }
                    )) { source = source, position = before };
                }
                if(source.getLexemeKind(position) != L_NAME)
                {
                    throw new TextSourceException(package.getResourceString("expected.name.argument")) { source = source, position = position };
                }
                String argumentName = source.getLexemeString(position);
                if(universalHolder.contains(argumentName))
                {
                    throw new TextSourceException(String.format(package.getResourceString("duplicate.name.argument"), new Object[] { argumentName })) { source = source, position = position };
                }
                universalHolder.append(argumentName);
                arguments[index++] = createLocal(isFinal, argumentType, argumentName, null, source, position);
                switch(source.getLexemeKind(++position))
                {
                default:
                    throw new TextSourceException(package.getResourceString("expected.comma-or-closed-parenth")) { source = source, position = position };
                case PARENTH_CLOSED:
                    arguments.length = index;
                    position++;
                    break label0;
                case COMMA:
                    position++;
                }
            }
            throw new TextSourceException(package.getResourceString("too-many.arguments")) { source = source, position = position };
        }
        return position;
    }

    private int parseThrowsClause(TextSource source, int position, ClassType enclosing, Method method) throws TextSourceException {
        TableBuilderClassTypeHolder throwTypeHolder = new TableBuilderClassTypeHolder();
        do
        {
            int before = position;
            position = parseClassName(source, position, enclosing, throwTypeHolder);
            ClassType type = throwTypeHolder.resultClassType;
            String name = type.specialCanonicalName;
            if(!name.equals(PACKNAME_LANG + "." + TYPENAME_THROWABLE) && !type.isSuperclass(PACKNAME_LANG + "." + TYPENAME_THROWABLE))
            {
                throw new TextSourceException(String.format(
                    package.getResourceString("can-not-be.thrown"), new Object[] { name, PACKNAME_LANG + "." + TYPENAME_THROWABLE }
                )) { source = source, position = before };
            }
            if(method.isThrows(type))
            {
                throw new TextSourceException(String.format(package.getResourceString("duplicate.exception.type"), new Object[] { name })) { source = source, position = before };
            }
            method.appendThrowable(type, before);
            if(source.getLexemeKind(position) != COMMA) break;
            position++;
        } while(true);
        return position;
    }
}

class TableBuilderClassTypeHolder(Object, TypeHolder)
{
    protected ClassType fldResultClassType;

    public () {  }

    public boolean helpersAllowed { read = false }

    public Type resultType { read = fldResultClassType, write = setResultType }

    public ClassType resultClassType { read = fldResultClassType, write = fldResultClassType }

    protected void setResultType(Type newResultType) {
        if(newResultType != null && !(newResultType instanceof ClassType))
        {
            throw new IllegalArgumentException(String.format(avt.lang.package.getResourceString("illegal-argument.must-have-type"), new Object[] { "newResultType", ClassType.class.simpleName }));
        }
        fldResultClassType = (ClassType) newResultType;
    }
}

class TableBuilderOperatorAndTypeHolder(Object, OperatorHolder, TypeHolder)
{
    protected int fldResultKind;
    protected Type fldResultType;

    public () {  }

    public int resultKind { read = fldResultKind, write = fldResultKind }

    public boolean helpersAllowed { read = false }

    public Type resultType { read = fldResultType, write = fldResultType }
}

final class TableBuilderSourcesLexer(Object, CompilerRunnable)
{
    private Lexer fldLexer;

    public (Lexer lexer) { fldLexer = lexer; }

    public void run(Object target) throws TextSourceException {
        TextSource source = (TextSource) target;
        String[] content = source.contents.clone();
        int length = content == null ? 0 : content.length;
        char[][] lines = new char[length][];
        char[] empty = new char[1];
        for(int index = length; index-- > 0; )
        {
            String line = content[index];
            if((length = line == null ? 0 : line.length) <= 0)
            {
                lines[index] = empty;
                continue;
            }
            char[] sequence = new char[length + 1];
            line.getChars(0, length, sequence, 0);
            lines[index] = sequence;
        }
        fldLexer.split(lines, 0, Int2.MAX_VALUE, source);
    }
}

final class TableBuilderSourcesParser(Object, CompilerRunnable, AVTOOConstants)
{
    public () {  }

    public void run(Object target) throws TextSourceException {
        TableBuilderTextSource source = (TableBuilderTextSource) target;
        if(Project.isPackageSourceFileName(source.outputPath) || source.getLexemeKind(0) == L_END) return;
        int kind;
        int position = 0;
        do
        {
            if((kind = source.getLexemeKind(++position)) == L_END) return;
        } while(kind != SEMICOLON);
        int tlength = 1;
        int tcapacity = 0x0f;
        int[][] tree = new int[tcapacity][];
        label0:
        {
            if((kind = source.getLexemeKind(++position)) != IMPORT)
            {
                tree[0] = new int[] { -1 };
            } else
            {
                tree[0] = new int[] { position };
                do
                {
                    do
                    {
                        if((kind = source.getLexemeKind(++position)) == L_END) break label0;
                    } while(kind != SEMICOLON);
                } while((kind = source.getLexemeKind(++position)) == IMPORT);
            }
            if(kind == L_END)
            {
                throw new TextSourceException(package.getResourceString("expected.definition.type")) { source = source, position = position };
            }
            do
            {
                int blength = 1;
                int bcapacity = 0x0f;
                int[] buffer = new int[bcapacity];
                buffer[0] = position;
                label1:
                {
                    do
                    {
                        if((kind = source.getLexemeKind(++position)) == L_END) break label1;
                    } while(kind != CURLY_OPENED);
                    while((kind = source.getLexemeKind(++position)) != L_END && kind != CURLY_CLOSED)
                    {
                        if(blength == bcapacity) Array.copy(buffer, 0, buffer = new int[bcapacity = bcapacity << 1 | 1], 0, blength);
                        buffer[blength++] = position;
                        boolean isField = false;
                        int equalsPosition = -1;
                        label2: do
                        {
                            switch(kind)
                            {
                            case L_END:
                                break label1;
                            case COLON:
                            case SEMICOLON:
                            case CURLY_OPENED:
                                break label2;
                            case L_NAME:
                                equalsPosition = position + 1;
                                break;
                            case EQUALS:
                                if(equalsPosition == position)
                                {
                                    isField = true;
                                    break label2;
                                }
                            }
                            kind = source.getLexemeKind(++position);
                        } while(true);
                        if(kind != SEMICOLON)
                        {
                            int end = isField ? SEMICOLON : CURLY_CLOSED;
                            int parenth = 0;
                            int bracket = 0;
                            int curly = 0;
                            do
                            {
                                switch(kind)
                                {
                                case CURLY_OPENED:
                                    curly++;
                                    break;
                                case CURLY_CLOSED:
                                    if(curly-- == 0)
                                    {
                                        throw new TextSourceException(package.getResourceString("extra.curly")) { source = source, position = position };
                                    }
                                    break;
                                case BRACKET_OPENED:
                                    bracket++;
                                    break;
                                case BRACKET_CLOSED:
                                    if(bracket-- == 0)
                                    {
                                        throw new TextSourceException(package.getResourceString("extra.bracket")) { source = source, position = position };
                                    }
                                    break;
                                case PARENTH_OPENED:
                                    parenth++;
                                    break;
                                case PARENTH_CLOSED:
                                    if(parenth-- == 0)
                                    {
                                        throw new TextSourceException(package.getResourceString("extra.parenth")) { source = source, position = position };
                                    }
                                    break;
                                case L_END:
                                    if(curly > 0)
                                    {
                                        throw new TextSourceException(package.getResourceString("not-closed.curly")) { source = source, position = position };
                                    }
                                    if(bracket > 0)
                                    {
                                        throw new TextSourceException(package.getResourceString("not-closed.bracket")) { source = source, position = position };
                                    }
                                    if(parenth > 0)
                                    {
                                        throw new TextSourceException(package.getResourceString("not-closed.parenth")) { source = source, position = position };
                                    }
                                    break label1;
                                }
                                if(kind == end && (curly | bracket | parenth) == 0) break;
                                kind = source.getLexemeKind(++position);
                            } while(true);
                        }
                    }
                }
                if(kind == L_END)
                {
                    throw new TextSourceException(package.getResourceString("unexpected-end.source")) { source = source, position = position };
                }
                if(blength == bcapacity) Array.copy(buffer, 0, buffer = new int[bcapacity = bcapacity << 1 | 1], 0, blength);
                buffer[blength++] = position;
                buffer.length = blength;
                if(tlength == tcapacity) Array.copy(tree, 0, tree = new int[tcapacity = tcapacity << 1 | 1][], 0, tlength);
                tree[tlength++] = buffer;
            } while(source.getLexemeKind(++position) != L_END);
        }
        tree.length = tlength;
        source.parsingTree = tree;
    }
}

final class TableBuilderSourcesReader(Object, CompilerRunnable, AVTOORecompilable, AVTOOConstants)
{
    private final TableBuilder fldTableBuilder;

    public (TableBuilder tableBuilder) { fldTableBuilder = tableBuilder; }

    public void run(Object target) throws BinarySourceException, IOException {
        BinarySource source = (BinarySource) target;
        ChunkArray chunks = source.chunks;
        int length = chunks.length;
        if(length-- < 3)
        {
            throw new BinarySourceException(package.getResourceString("binary.chunk.too-low")) { source = source, offset = 0 };
        }
        Chunk version = chunks[0];
        Chunk constants = chunks[1];
        Chunk end = chunks[length];
        if(version.type != CHUNK_VERS)
        {
            throw new BinarySourceException(package.getResourceString("binary.chunk.1st")) { source = source, position = 0 };
        }
        if(constants.type != CHUNK_CONS)
        {
            throw new BinarySourceException(package.getResourceString("binary.chunk.2nd")) { source = source, position = 1 };
        }
        if(end.type != CHUNK_IEND)
        {
            throw new BinarySourceException(package.getResourceString("binary.chunk.last")) { source = source, position = length };
        }
        if(version.readInt() != VERSION_AVTR)
        {
            throw new BinarySourceException(package.getResourceString("binary.unsupported-version")) { source = source, offset = version.dataOffsetToSourceOffset(0) };
        }
        Vector vector = (new Vector()) + null;
        for(Programme programme = fldTableBuilder; constants.available() > 0; ) switch(constants.readUnsignedShort())
        {
        case CONST_Z:
            vector + constants.readBoolean();
            break;
        case CONST_C:
            vector + constants.readChar();
            break;
        case CONST_R:
            vector + constants.readReal();
            break;
        case CONST_D:
            vector + constants.readDouble();
            break;
        case CONST_D2:
            vector + constants.readDouble2();
            break;
        case CONST_D4:
            vector + constants.readDouble4();
            break;
        case CONST_D8:
            vector + constants.readDouble8();
            break;
        case CONST_F:
            vector + constants.readFloat();
            break;
        case CONST_F2:
            vector + constants.readFloat2();
            break;
        case CONST_F4:
            vector + constants.readFloat4();
            break;
        case CONST_F8:
            vector + constants.readFloat8();
            break;
        case CONST_B:
            vector + (byte) constants.readByte();
            break;
        case CONST_B2:
            vector + constants.readByte2();
            break;
        case CONST_B4:
            vector + constants.readByte4();
            break;
        case CONST_B8:
            vector + constants.readByte8();
            break;
        case CONST_S:
            vector + (short) constants.readShort();
            break;
        case CONST_S2:
            vector + constants.readShort2();
            break;
        case CONST_S4:
            vector + constants.readShort4();
            break;
        case CONST_S8:
            vector + constants.readShort8();
            break;
        case CONST_I:
            vector + constants.readInt();
            break;
        case CONST_I2:
            vector + constants.readInt2();
            break;
        case CONST_I4:
            vector + constants.readInt4();
            break;
        case CONST_I8:
            vector + constants.readInt8();
            break;
        case CONST_J:
            vector + constants.readLong();
            break;
        case CONST_J2:
            vector + constants.readLong2();
            break;
        case CONST_J4:
            vector + constants.readLong4();
            break;
        case CONST_J8:
            vector + constants.readLong8();
            break;
        case CONST_ST:
            char[] chars = new char[constants.readUnsignedShort()];
            constants.readFully(chars);
            vector + new String(chars);
            break;
        case CONST_PK:
            int name = constants.readInt();
            vector + new PackageElement(programme, name);
            break;
        case CONST_TP:
            int name = constants.readInt();
            vector + new TypeElement(programme, name);
            break;
        case CONST_FL:
            int type = constants.readInt();
            int name = constants.readInt();
            vector + new FieldElement(programme, type, name);
            break;
        case CONST_PR:
            int type = constants.readInt();
            int name = constants.readInt();
            vector + new PropertyElement(programme, type, name);
            break;
        case CONST_CL:
            int type = constants.readInt();
            int name = constants.readInt();
            if((length = constants.readUnsignedShort()) > LIMIT_ARGUMENTS_LENGTH)
            {
                throw new BinarySourceException(package.getResourceString("too-many.arguments.class-member")) { source = source, offset = constants.dataOffsetToSourceOffset(constants.position) };
            }
            int[] args = new int[length];
            for(int index = 0; index < length; index++) args[index] = constants.readInt();
            vector + new CallableElement(programme, type, name, args);
            break;
        default:
            throw new BinarySourceException(package.getResourceString("unknown.type.constant")) { source = source, offset = constants.dataOffsetToSourceOffset(constants.position) };
        }
        for(Object[] store = vector.toObjectArray(), source[1] = store, int index = store.length; index-- > 0; )
        {
            Object element = store[index];
            if(element instanceof RecompilableElement) ((RecompilableElement) element).constants = store;
        }
    }
}

final class TableBuilderTextSource(TextSource, CharsetInputAdapter, InputAdapter, Source, Cloneable, Measureable, MutableObjectArray, ObjectArray, AVTOOConstants)
{
    private int[][] fldParsingTree;

    public (Library parentLibrary, String relativePath): super(parentLibrary, relativePath) {  }

    public final int[][] parsingTree { read = fldParsingTree, write = fldParsingTree }
}

class TableBuilderVectorAndTypeHolder(Vector, TypeHolder)
{
    protected Type fldResultType;

    public (int initialCapacity): super(initialCapacity) {  }

    public boolean helpersAllowed { read = false }

    public Type resultType { read = fldResultType, write = fldResultType }
}