/*
Компилятор языка программирования
Объектно-ориентированный продвинутый векторный транслятор
Copyright © 2021, 2024 Малик Разработчик
Это свободная программа: вы можете перераспространять ее и/или изменять
ее на условиях Стандартной общественной лицензии GNU в том виде,
в каком она была опубликована Фондом свободного программного обеспечения;
либо версии 3 лицензии, либо (по вашему выбору) любой более поздней версии.
Эта программа распространяется в надежде, что она будет полезной,
но БЕЗО ВСЯКИХ ГАРАНТИЙ; даже без неявной гарантии ТОВАРНОГО ВИДА
или ПРИГОДНОСТИ ДЛЯ ОПРЕДЕЛЕННЫХ ЦЕЛЕЙ. Подробнее см. в Стандартной
общественной лицензии GNU.
Вы должны были получить копию Стандартной общественной лицензии GNU
вместе с этой программой. Если это не так, см.
<https://www.gnu.org/licenses/>.
*/
package ru.malik.elaborarer.avtoo.lang;
import avt.lang.array.*;
public class Method(Callable, Cloneable, Measureable, ObjectArray, TypedItem, TypedMember, AVTOOConstants)
{
private int fldThrowablesLength;
private int[] fldThrowablesPositions;
private ClassType[] fldThrowablesTypes;
private ClassType fldFirstNonFreeThrowableType;
public (ClassType parentType, int attributes, Type type, String specialSimpleName, Local[] arguments, int declarationPosition, int documentationPosition):
super(parentType, attributes, type, specialSimpleName, arguments, declarationPosition, documentationPosition) {
}
public boolean canThrown() { return fldFirstNonFreeThrowableType != null; }
public boolean canThrown(ClassType throwable) {
if(throwable == null) return false;
if(throwable.isFreeThrowableType()) return true;
for(ClassType[] types = fldThrowablesTypes, int index = fldThrowablesLength; index-- > 0; ) if(types[index].isAssignableFrom(throwable)) return true;
return false;
}
public String toString() {
ClassType enclosing = parentType;
return enclosing == null ? super.toString() + arguments.toString() : (new StringBuilder() + enclosing.specialCanonicalName + '.' + specialSimpleName + arguments).toString();
}
public void appendThrowable(ClassType throwable, int position) {
if(throwable == null)
{
throw new NullPointerException(String.format(avt.lang.package.getResourceString("null-pointer.argument"), new Object[] { "throwable" }));
}
if(throwable.parentProgramme != parentProgramme)
{
throw new IllegalArgumentException(package.getResourceString("throwable-type.not-same-programme"));
}
int length = fldThrowablesLength;
ClassType[] types = fldThrowablesTypes;
if(Array.indexOf(throwable, types, 0, length) >= 0)
{
throw new IllegalArgumentException(String.format(package.getResourceString("throwable-type.already-added"), new Object[] { throwable }));
}
int[] poses = fldThrowablesPositions;
if(types == null)
{
fldThrowablesPositions = poses = new int[0x0f];
fldThrowablesTypes = types = new ClassType[0x0f];
}
else if(length == types.length)
{
if(length == Int.MAX_VALUE)
{
throw new BufferTooLargeError(avt.lang.package.getResourceString("!error.buffer-too-large"));
}
int capacity = length << 1 | 1;
Array.copy(poses, 0, fldThrowablesPositions = poses = new int[capacity], 0, length);
Array.copy(types, 0, fldThrowablesTypes = types = new ClassType[capacity], 0, length);
}
poses[length] = position;
types[length++] = throwable;
fldThrowablesLength = length;
if(fldFirstNonFreeThrowableType == null && !throwable.isFreeThrowableType())
{
fldFirstNonFreeThrowableType = throwable;
}
}
public final boolean isThrows(ClassType throwable) {
if(throwable == null) return false;
int length = fldThrowablesLength;
return length > 0 && Array.indexOf(throwable, fldThrowablesTypes, 0, length) >= 0;
}
public final int getThrowablesLength() { return fldThrowablesLength; }
public final int getThrowablePositionAt(int index) {
if(index < 0 || index >= fldThrowablesLength)
{
throw new ArrayIndexOutOfBoundsException(avt.lang.package.getResourceString("out-of-bounds.array-index"));
}
return fldThrowablesPositions[index];
}
public final ClassType getThrowableTypeAt(int index) {
if(index < 0 || index >= fldThrowablesLength)
{
throw new ArrayIndexOutOfBoundsException(avt.lang.package.getResourceString("out-of-bounds.array-index"));
}
return fldThrowablesTypes[index];
}
public final ClassType firstNonFreeThrowableType() { return fldFirstNonFreeThrowableType; }
protected String composeFasmSimpleName() { return specialSimpleName; }
}