Callable.avt

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

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

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

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

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

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

package ru.malik.elaborarer.avtoo.lang;

import avt.lang.array.*;
import avt.util.*;

public abstract class Callable(OverriddableMember, Cloneable, Measureable, ObjectArray, TypedItem, TypedMember, AVTOOConstants)
{
    private int fldVirtualIndex;
    private int fldServiceIndex;
    private final Local[] fldArgumentsStore;
    private final ArgumentArray fldArgumentsArray;
    private final Hashtable fldArgumentsTable;
    private final Local fldThisArgument;
    private final Code fldCode;

    protected (ClassType parentType, int attributes, Type type, String specialSimpleName, Local[] arguments, int declarationPosition, int documentationPosition):
        super(parentType, attributes, type, specialSimpleName, declarationPosition, documentationPosition) {
        int length = arguments == null ? 0 : arguments.length;
        Local[] otherArguments = new Local[length];
        Array.copy(arguments, 0, otherArguments, 0, length);
        if(Array.indexOf(null, otherArguments, 0, 0) >= 0)
        {
            throw new NullPointerException(String.format(avt.lang.package.getResourceString("null-pointer.argument.component"), new Object[] { "arguments" }));
        }
        for(Local argument = length <= 0 ? null : otherArguments[0], int index = 1; index < length; argument = otherArguments[index++]) if(Array.indexOf(argument, otherArguments, index, 0) >= 0)
        {
            throw new IllegalArgumentException(String.format(avt.lang.package.getResourceString("illegal-argument.component.two-ones-is-equal"), new Object[] { "arguments" }));
        }
        for(int index = length; index-- > 0; ) if(otherArguments[index].type == null)
        {
            throw new IllegalArgumentException(String.format(avt.lang.package.getResourceString("illegal-argument.component.uninitialized-property"), new Object[] { "arguments", "type" }));
        }
        Local thisArgument = (attributes & ATTR_STATIC) != 0 || parentType == null ? null : parentType.thisArgument;
        Hashtable table = thisArgument == null && length <= 0 ? null : new Hashtable();
        for(int index = length; index-- > 0; )
        {
            Local argument = otherArguments[index];
            String name = argument.specialSimpleName;
            if(name != null) table[name] = argument;
        }
        if(thisArgument != null)
        {
            String name = thisArgument.specialSimpleName;
            if(name != null) table[name] = thisArgument;
        }
        fldVirtualIndex = -1;
        fldServiceIndex = -1;
        fldArgumentsStore = otherArguments;
        fldArgumentsArray = new ArgumentArray(thisArgument, otherArguments);
        fldArgumentsTable = table;
        fldThisArgument = thisArgument;
        fldCode = (attributes & (ATTR_ABSTRACT | ATTR_NATIVE)) != 0 ? null : createCode();
    }

    public boolean isOverrides(OverriddableMember anot) { return super.isOverrides(anot) && isIdentityArguments(((Callable) anot).fldArgumentsStore); }

    public boolean canThrown() { return false; }

    public boolean canThrown(ClassType throwable) { return throwable != null && throwable.isFreeThrowableType(); }

    public final boolean isNative() { return (attributes & ATTR_NATIVE) != 0; }

    public final boolean isInterrupt() { return (attributes & ATTR_INTERRUPT) != 0; }

    public final boolean isSynchronized() { return (attributes & ATTR_SYNCHRONIZED) != 0; }

    public final boolean isArgument(Local argument) { return argument != null && (argument == fldThisArgument || Array.indexOf(argument, fldArgumentsStore, 0, 0) >= 0); }

    public final boolean isIdentityArguments(Callable member) { return member != null && isIdentityArguments(member.fldArgumentsStore); }

    public final boolean isIdentityArguments(Type[] arguments) {
        int length = arguments == null ? 0 : arguments.length;
        Local[] store = fldArgumentsStore;
        if(length != store.length)
        {
            return false;
        }
        for(int index = 0; index < length; index++)
        {
            if(arguments[index] != store[index].type) return false;
        }
        return true;
    }

    public final boolean isIdentityArguments(TypedItem[] arguments) {
        int length = arguments == null ? 0 : arguments.length;
        Local[] store = fldArgumentsStore;
        if(length != store.length)
        {
            return false;
        }
        for(int index = 0; index < length; index++)
        {
            TypedItem argument = arguments[index];
            if(argument == null || argument.type != store[index].type) return false;
        }
        return true;
    }

    public final boolean isAssignableArguments(Type[] arguments) {
        int length = arguments == null ? 0 : arguments.length;
        Local[] store = fldArgumentsStore;
        if(length != store.length)
        {
            return false;
        }
        for(int index = 0; index < length; index++)
        {
            Type type = arguments[index];
            if(type == null || !store[index].type.isAssignableFrom(type)) return false;
        }
        return true;
    }

    public final boolean isConvertableArguments(Type[] arguments) {
        int length = arguments == null ? 0 : arguments.length;
        Local[] store = fldArgumentsStore;
        if(length != store.length)
        {
            return false;
        }
        for(int index = 0; index < length; index++)
        {
            Type type = arguments[index];
            if(type == null || !store[index].type.isConvertableFrom(type)) return false;
        }
        return true;
    }

    public final Local getArgument(String specialSimpleName) {
        if(specialSimpleName == null) return null;
        Hashtable table = fldArgumentsTable;
        return table == null ? null : (Local) table[specialSimpleName];
    }

    public final int virtualIndex { read = fldVirtualIndex }

    public final int serviceIndex { read = fldServiceIndex }

    public final ArgumentArray arguments { read = fldArgumentsArray }

    public final Code code { read = fldCode }

    protected abstract String composeFasmSimpleName();

    protected String composeFasmFullName() {
        ClassType enclosing = parentType;
        return (new StringBuilder() + (enclosing != null ? enclosing.fasmFullName : "") + '$' + fasmSimpleName + fldArgumentsArray.toFasmString()).toString();
    }

    package final void setVirtualIndex(int virtualIndex) { fldVirtualIndex = virtualIndex; }

    package final void setServiceIndex(int serviceIndex) { fldServiceIndex = serviceIndex; }

    private Code createCode() {
        Programme programme = parentProgramme;
        Code result = programme == null ? null : programme.newCode(this);
        if(result == null) result = new Code(this);
        return result;
    }
}