/*
Компилятор языка программирования
Объектно-ориентированный продвинутый векторный транслятор
Copyright © 2021, 2024 Малик Разработчик
Это свободная программа: вы можете перераспространять ее и/или изменять
ее на условиях Стандартной общественной лицензии GNU в том виде,
в каком она была опубликована Фондом свободного программного обеспечения;
либо версии 3 лицензии, либо (по вашему выбору) любой более поздней версии.
Эта программа распространяется в надежде, что она будет полезной,
но БЕЗО ВСЯКИХ ГАРАНТИЙ; даже без неявной гарантии ТОВАРНОГО ВИДА
или ПРИГОДНОСТИ ДЛЯ ОПРЕДЕЛЕННЫХ ЦЕЛЕЙ. Подробнее см. в Стандартной
общественной лицензии GNU.
Вы должны были получить копию Стандартной общественной лицензии GNU
вместе с этой программой. Если это не так, см.
<https://www.gnu.org/licenses/>.
*/
package ru.malik.elaborarer.avtoo.lang;
import avt.lang.array.*;
public class ClassType(ReferenceType, Cloneable, Measureable, ObjectArray, AllocatableFactory, AVTOOConstants)
{
private boolean fldStructMarked;
private int fldNativeCallablesCounter;
private int fldStructSize;
private int fldInstanceSize;
private int fldHelperForPosition;
private int fldSuperclassPosition;
private int fldSuperservicesLength;
private int fldUserMembersInsertionPosition;
private int[] fldSuperservicesPositions;
private Callable[] fldVirtualCallables;
private Callable[] fldServiceCallables;
private ClassType[] fldSuperservicesTypes;
private ClassType fldSuperclassType;
private ClassType fldHelperForType;
private InstInit fldDefaultConstructor;
private ClassInit fldStaticBlock;
private FieldsMap fldFieldsMap;
private Local fldThisArgument;
private final String fldOutputPath;
private final ClassTypeArray fldHelpers;
private final ClassTypeArray fldSubtypes;
public (Package parentPackage, int attributes, String specialSimpleName, Source source, int declarationPosition, int documentationPosition, String outputPath):
super(parentPackage, attributes, specialSimpleName, source, declarationPosition, documentationPosition) {
boolean isHelper = isHelper();
fldHelperForPosition = -1;
fldSuperclassPosition = -1;
fldThisArgument = isHelper ? null : createThisArgument();
fldOutputPath = outputPath;
fldHelpers = isHelper ? null : new ClassTypeArray();
fldSubtypes = (attributes &= MASK_TYPE | ATTR_FINAL) != 0 && attributes != ATTR_STRUCT ? null : new ClassTypeArray();
}
public boolean isAssignableFrom(Type anot) {
if(anot == null)
{
throw new NullPointerException(String.format(avt.lang.package.getResourceString("null-pointer.argument"), new Object[] { "anot" }));
}
return anot == this || anot.isNull() || anot instanceof ClassType && (isService() ? ((ClassType) anot).isSuperservice(this) : ((ClassType) anot).isSuperclass(this));
}
public boolean isCompatibleWith(Type anot) {
if(anot == null)
{
throw new NullPointerException(String.format(avt.lang.package.getResourceString("null-pointer.argument"), new Object[] { "anot" }));
}
if(anot.isNull())
{
return true;
}
if(!(anot instanceof ClassType))
{
return false;
}
boolean thisIsFinal = isFinal();
boolean thisIsService = isService();
boolean anotIsFinal = anot.isFinal();
boolean anotIsService = anot.isService();
ClassType type = (ClassType) anot;
ClassType thisSuperclass = fldSuperclassType;
ClassType anotSuperclass = type.fldSuperclassType;
return thisIsService ? (
anotIsService ? (
thisSuperclass == anotSuperclass ||
thisSuperclass.isSuperclass(anotSuperclass) ||
anotSuperclass.isSuperclass(thisSuperclass)
) : (
anotIsFinal ? (
type.isSuperservice(this)
) : (
thisSuperclass == type ||
thisSuperclass.isSuperclass(type) ||
type.isSuperclass(thisSuperclass)
)
)
) : (
anotIsService ? (
thisIsFinal ? (
isSuperservice(type)
) : (
this == anotSuperclass ||
isSuperclass(anotSuperclass) ||
anotSuperclass.isSuperclass(this)
)
) : (
this == type ||
isSuperclass(type) ||
type.isSuperclass(this)
)
);
}
public boolean isClass() { return (attributes & MASK_TYPE) == 0; }
public boolean isStruct() { return (attributes & MASK_TYPE) == ATTR_STRUCT; }
public boolean isService() { return (attributes & (ATTR_PRIMITIVE | ATTR_SERVICE)) == ATTR_SERVICE; }
public boolean isInterface() { return (attributes & MASK_TYPE) == ATTR_INTERFACE; }
public boolean isHelper() { return (attributes & (MASK_BINDING | MASK_TYPE)) == (ATTR_FINAL | ATTR_SERVICE); }
public ClassType getRealType() { return !isHelper() ? this : fldHelperForType; }
public Union createNestedUnion(int declarationPosition, int documentationPosition) {
if(!isStruct())
{
throw new IllegalClassTypeStateException(package.getResourceString("class-type.not-a-struct"));
}
return AllocatableFactory.super.createNestedUnion(declarationPosition, documentationPosition);
}
public Struct createNestedStruct(int declarationPosition, int documentationPosition) {
if(!isStruct())
{
throw new IllegalClassTypeStateException(package.getResourceString("class-type.not-a-struct"));
}
return AllocatableFactory.super.createNestedStruct(declarationPosition, documentationPosition);
}
public Field createStructField(Type type, int capacity, String specialSimpleName, int declarationPosition, int documentationPosition) {
if(!isStruct())
{
throw new IllegalClassTypeStateException(package.getResourceString("class-type.not-a-struct"));
}
return AllocatableFactory.super.createStructField(type, capacity, specialSimpleName, declarationPosition, documentationPosition);
}
public void removeStaticBlock() {
Member member = fldStaticBlock;
if(member != null)
{
if(!member.isSynthetic()) fldUserMembersInsertionPosition--;
removeChildItem(member);
}
}
public void initHelperFor(ClassType target, int position) {
if(!isHelper())
{
throw new IllegalClassTypeStateException(package.getResourceString("class-type.can-not-init-targettype"));
}
if(fldHelperForType != null)
{
throw new IllegalClassTypeStateException(package.getResourceString("class-type.initialized-targettype"));
}
if(target == null)
{
throw new NullPointerException(String.format(avt.lang.package.getResourceString("null-pointer.argument"), new Object[] { "target" }));
}
if(target.parentProgramme != parentProgramme)
{
throw new IllegalArgumentException(package.getResourceString("target-type.not-same-programme"));
}
if(target.isHelper())
{
throw new IllegalArgumentException(package.getResourceString("target-type.is-a-helper"));
}
fldHelperForPosition = position;
fldHelperForType = target;
fldThisArgument = target.fldThisArgument;
target.fldHelpers.append(this);
}
public void initSuperclass(ClassType superclass, int position) {
if(isHelper())
{
throw new IllegalClassTypeStateException(package.getResourceString("class-type.can-not-init-superclass"));
}
if(fldSuperclassType != null)
{
throw new IllegalClassTypeStateException(package.getResourceString("class-type.initialized-superclass"));
}
if(superclass == null)
{
throw new NullPointerException(String.format(avt.lang.package.getResourceString("null-pointer.argument"), new Object[] { "superclass" }));
}
if(superclass.parentProgramme != parentProgramme)
{
throw new IllegalArgumentException(package.getResourceString("superclass.not-same-programme"));
}
if(superclass.isHelper())
{
throw new IllegalArgumentException(package.getResourceString("superclass.is-a-helper"));
}
if(superclass.isService())
{
throw new IllegalArgumentException(package.getResourceString("superclass.is-a-service"));
}
fldSuperclassPosition = position;
fldSuperclassType = superclass;
}
public void appendSuperservice(ClassType superservice, int position) {
if(isHelper())
{
throw new IllegalClassTypeStateException(package.getResourceString("class-type.can-not-add-superservice"));
}
if(superservice == null)
{
throw new NullPointerException(String.format(avt.lang.package.getResourceString("null-pointer.argument"), new Object[] { "superservice" }));
}
if(superservice.parentProgramme != parentProgramme)
{
throw new IllegalArgumentException(package.getResourceString("superservice.not-same-programme"));
}
if(superservice.isHelper())
{
throw new IllegalArgumentException(package.getResourceString("superservice.is-a-helper"));
}
if(!superservice.isService())
{
throw new IllegalArgumentException(package.getResourceString("superservice.not-a-service"));
}
int length = fldSuperservicesLength;
ClassType[] types = fldSuperservicesTypes;
if(Array.indexOf(superservice, types, 0, length) >= 0)
{
throw new IllegalArgumentException(String.format(package.getResourceString("class-type.added-superservice"), new Object[] { superservice }));
}
int[] poses = fldSuperservicesPositions;
if(types == null)
{
fldSuperservicesPositions = poses = new int[0x0f];
fldSuperservicesTypes = 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, fldSuperservicesPositions = poses = new int[capacity], 0, length);
Array.copy(types, 0, fldSuperservicesTypes = types = new ClassType[capacity], 0, length);
}
poses[length] = position;
types[length++] = superservice;
fldSuperservicesLength = length;
}
public void appendImpliedSuperservices() {
if(isHelper()) return;
int tindex = -1;
int tlength = fldSuperservicesLength;
int[] poses = fldSuperservicesPositions;
ClassType[] types = fldSuperservicesTypes;
ClassType current = fldSuperclassType;
if(current == null && tlength > 0)
{
current = types[0];
tindex = 1;
}
while(current != null)
{
int slength = current.fldSuperservicesLength;
ClassType[] supers = current.fldSuperservicesTypes;
for(int sindex = 0; sindex < slength; sindex++)
{
ClassType superservice = supers[sindex];
if(Array.indexOf(superservice, types, 0, tlength) < 0)
{
if(types == null)
{
fldSuperservicesPositions = poses = new int[0x0f];
fldSuperservicesTypes = types = new ClassType[0x0f];
}
else if(tlength == types.length)
{
if(tlength == Int.MAX_VALUE)
{
throw new BufferTooLargeError(avt.lang.package.getResourceString("!error.buffer-too-large"));
}
int capacity = tlength << 1 | 1;
Array.copy(poses, 0, fldSuperservicesPositions = poses = new int[capacity], 0, tlength);
Array.copy(types, 0, fldSuperservicesTypes = types = new ClassType[capacity], 0, tlength);
}
poses[tlength] = -1;
types[tlength++] = superservice;
}
}
if(tindex < 0 && (current = current.fldSuperclassType) == null)
{
tindex = 0;
}
if(tindex >= 0)
{
current = tindex >= tlength ? null : types[tindex];
tindex++;
}
}
fldSuperservicesLength = tlength;
}
public boolean isFreeThrowableType() {
String name = specialCanonicalName;
return
name.equals(PACKNAME_LANG + "." + TYPENAME_ERROR) ||
isSuperclass(PACKNAME_LANG + "." + TYPENAME_ERROR) ||
name.equals(PACKNAME_LANG + "." + TYPENAME_RUNTIME_EXCEPTION) ||
isSuperclass(PACKNAME_LANG + "." + TYPENAME_RUNTIME_EXCEPTION)
;
}
public Field createStructField(int structOffset, Type type, int capacity, String specialSimpleName, int declarationPosition, int documentationPosition) {
if(!isStruct())
{
throw new IllegalClassTypeStateException(package.getResourceString("class-type.not-a-struct"));
}
if(structOffset < 0)
{
throw new IllegalArgumentException(package.getResourceString("negative.offset"));
}
if(type == null)
{
throw new NullPointerException(String.format(avt.lang.package.getResourceString("null-pointer.argument"), new Object[] { "type" }));
}
Programme programme = parentProgramme;
if(type.parentProgramme != programme)
{
throw new IllegalArgumentException(package.getResourceString("type.not-same-programme.type"));
}
if(capacity > LIMIT_FIELD_LENGTH)
{
throw new IllegalArgumentException(String.format(package.getResourceString("field.length-too-large"), new Object[] { Int.toString(LIMIT_FIELD_LENGTH) }));
}
if(type.isVoid() || type.isNull() || (capacity <= 0 ? !type.isPrimitive() : !(type instanceof ArrayType) || !((ArrayType) type).componentType.isPrimitive()))
{
throw new IllegalArgumentException(package.getResourceString("type.not-suitable.field"));
}
Field result = programme == null ? null : programme.newStructField(this, structOffset, type, capacity, specialSimpleName, declarationPosition, documentationPosition);
if(result == null) result = new Field(this, structOffset, type, capacity, specialSimpleName, declarationPosition, documentationPosition);
appendChildItem(result);
return result;
}
public Field createClassField(int attributes, Type type, String specialSimpleName, int declarationPosition, int documentationPosition) {
if(type == null)
{
throw new NullPointerException(String.format(avt.lang.package.getResourceString("null-pointer.argument"), new Object[] { "type" }));
}
Programme programme = parentProgramme;
if(type.parentProgramme != programme)
{
throw new IllegalArgumentException(package.getResourceString("type.not-same-programme.type"));
}
if(type.isVoid() || type.isNull())
{
throw new IllegalArgumentException(package.getResourceString("type.not-suitable.field"));
}
Field result = programme == null ? null : programme.newClassField(this, attributes, type, specialSimpleName, declarationPosition, documentationPosition);
if(result == null)
{
result = new Field(this, attributes, type, specialSimpleName, declarationPosition, documentationPosition);
}
if((attributes & ATTR_SYNTHETIC) != 0)
{
appendChildItem(result);
} else
{
insertChildItem(result, fldUserMembersInsertionPosition++);
}
return result;
}
public ClassInit createStaticBlock(int attributes, int declarationPosition, int documentationPosition) {
Programme programme = parentProgramme;
ClassInit result = programme == null ? null : programme.newStaticBlock(this, attributes, declarationPosition, documentationPosition);
if(result == null)
{
result = new ClassInit(this, attributes, declarationPosition, documentationPosition);
}
if((attributes & ATTR_SYNTHETIC) != 0)
{
appendChildItem(result);
} else
{
insertChildItem(result, fldUserMembersInsertionPosition++);
}
return result;
}
public InstInit createConstructor(int attributes, Local[] arguments, int declarationPosition, int documentationPosition) {
Programme programme = parentProgramme;
InstInit result = programme == null ? null : programme.newConstructor(this, attributes, arguments, declarationPosition, documentationPosition);
if(result == null)
{
result = new InstInit(this, attributes, arguments, declarationPosition, documentationPosition);
}
if((attributes & ATTR_SYNTHETIC) != 0)
{
appendChildItem(result);
} else
{
insertChildItem(result, fldUserMembersInsertionPosition++);
}
return result;
}
public Method createMethod(int attributes, Type type, String specialSimpleName, Local[] arguments, int declarationPosition, int documentationPosition) {
if(type == null)
{
throw new NullPointerException(String.format(avt.lang.package.getResourceString("null-pointer.argument"), new Object[] { "type" }));
}
Programme programme = parentProgramme;
if(type.parentProgramme != programme)
{
throw new IllegalArgumentException(package.getResourceString("type.not-same-programme.type"));
}
if(type.isNull())
{
throw new IllegalArgumentException(package.getResourceString("type.not-suitable.method"));
}
Method result = programme == null ? null : programme.newMethod(this, attributes, type, specialSimpleName, arguments, declarationPosition, documentationPosition);
if(result == null)
{
result = new Method(this, attributes, type, specialSimpleName, arguments, declarationPosition, documentationPosition);
}
if((attributes & ATTR_SYNTHETIC) != 0)
{
appendChildItem(result);
} else
{
insertChildItem(result, fldUserMembersInsertionPosition++);
}
int position = specialSimpleName == null ? -1 : specialSimpleName.lastIndexOf('.');
if(position >= 0) for(ProgrammeItem member = super.getChildItem(specialSimpleName.substring(0, position++)); member != null; member = member.nextItem) if(member instanceof Property)
{
String suffix = specialSimpleName.substring(position);
if(suffix.equals(MEMBER_SUFFIX_READ))
{
((Property) member).setReadSynthetic(result);
break;
}
if(suffix.equals(MEMBER_SUFFIX_WRITE))
{
((Property) member).setWriteSynthetic(result);
break;
}
if(suffix.equals(MEMBER_SUFFIX_INDEX))
{
((Property) member).setIndexSynthetic(result);
break;
}
if(suffix.equals(MEMBER_SUFFIX_STORED))
{
((Property) member).setStoredSynthetic(result);
}
break;
}
return result;
}
public Operator createOperator(int attributes, Type type, int kind, Local[] arguments, int declarationPosition, int documentationPosition) {
if(type == null)
{
throw new NullPointerException(String.format(avt.lang.package.getResourceString("null-pointer.argument"), new Object[] { "type" }));
}
Programme programme = parentProgramme;
if(type.parentProgramme != programme)
{
throw new IllegalArgumentException(package.getResourceString("type.not-same-programme.type"));
}
if(type.isNull())
{
throw new IllegalArgumentException(package.getResourceString("type.not-suitable.operator"));
}
Operator result = programme == null ? null : programme.newOperator(this, attributes, type, kind, arguments, declarationPosition, documentationPosition);
if(result == null)
{
result = new Operator(this, attributes, type, kind, arguments, declarationPosition, documentationPosition);
}
if((attributes & ATTR_SYNTHETIC) != 0)
{
appendChildItem(result);
} else
{
insertChildItem(result, fldUserMembersInsertionPosition++);
}
return result;
}
public Property createProperty(int attributes, Type type, String specialSimpleName, int declarationPosition, int documentationPosition) {
if(type == null)
{
throw new NullPointerException(String.format(avt.lang.package.getResourceString("null-pointer.argument"), new Object[] { "type" }));
}
Programme programme = parentProgramme;
if(type.parentProgramme != programme)
{
throw new IllegalArgumentException(package.getResourceString("type.not-same-programme.type"));
}
if(type.isVoid() || type.isNull())
{
throw new IllegalArgumentException(package.getResourceString("type.not-suitable.property"));
}
Property result = programme == null ? null : programme.newProperty(this, attributes, type, specialSimpleName, declarationPosition, documentationPosition);
if(result == null)
{
result = new Property(this, attributes, type, specialSimpleName, declarationPosition, documentationPosition);
}
if((attributes & ATTR_SYNTHETIC) != 0)
{
appendChildItem(result);
} else
{
insertChildItem(result, fldUserMembersInsertionPosition++);
}
return result;
}
public final Member getChildItem(String specialSimpleName) { return (Member) super.getChildItem(specialSimpleName); }
public final Member getChildItem(String specialSimpleName, boolean ignoreCase) { return (Member) super.getChildItem(specialSimpleName, ignoreCase); }
public final void markupClass() {
if(isHelper()) return;
int instanceSize = 0;
int vlength = 0;
Callable[] vmethods;
ClassType superclass = fldSuperclassType;
FieldsMap fieldsMap;
if(superclass == null)
{
fieldsMap = new FieldsMap();
vmethods = new Callable[0x0f];
} else
{
if((fieldsMap = superclass.fldFieldsMap) == null || (vmethods = superclass.fldVirtualCallables) == null)
{
throw new IllegalClassTypeStateException(package.getResourceString("superclass.has-no-markup"));
}
fieldsMap = fieldsMap.clone();
instanceSize = superclass.fldInstanceSize;
vlength = vmethods.length;
Array.copy(vmethods, 0, vmethods = new Callable[vmethods.capacity], 0, vlength);
}
int mlength = length;
Member[] members = new Member[mlength];
for(int mindex = mlength; mindex-- > 0; )
{
((ProgrammeItem[]) members)[mindex] = super.operator [](mindex);
}
/* разметка инстанции */
{
boolean isStruct = isStruct();
for(int mindex = 0; mindex < mlength; mindex++)
{
Member member = members[mindex];
if(!member.isStatic() && member instanceof Field)
{
Field field = (Field) member;
String name = member.specialSimpleName;
if(!isStruct || field.type instanceof ReferenceType && name != null && !name.isEmpty())
{
int offsetAfter = field.computeInstanceOffset(instanceSize, fieldsMap);
if(instanceSize < offsetAfter) instanceSize = offsetAfter;
}
}
}
if(isStruct) instanceSize += -instanceSize & 0x3f;
fldFieldsMap = fieldsMap;
fldInstanceSize = instanceSize;
}
/* разметка таблицы виртуальных методов */
{
for(int vindex = 0; vindex < vlength; vindex++)
{
Callable callable = vmethods[vindex];
if(callable.isVisibleFrom(this, this))
{
Callable overrides = (Callable) callable.overridesIn(this, Callable.TYPE);
if(overrides != null) (vmethods[vindex] = overrides).setVirtualIndex(vindex);
}
}
ClassType[] stypes = getSubtypesStore();
int slength = stypes == null ? 0 : stypes.length;
if(slength > 0)
{
int olength = 0;
Callable[] omethods = new Callable[mlength];
for(int mindex = 0; mindex < mlength; mindex++)
{
Member member = members[mindex];
if(!member.isStatic() && member instanceof Callable && member.visibility > PRIVATE && !member.isFinal() && !member.isSpecial())
{
Callable callable = (Callable) member;
if(callable.virtualIndex < 0) omethods[olength++] = callable;
}
}
for(int oindex = 0; oindex < olength; oindex++)
{
for(Callable callable = omethods[oindex], int sindex = slength; sindex-- > 0; )
{
ClassType current = stypes[sindex];
if(callable.isVisibleFrom(current, current) && callable.overridesIn(current, Callable.TYPE) != null)
{
if(vlength == vmethods.capacity)
{
if(vlength == Int.MAX_VALUE)
{
throw new BufferTooLargeError(avt.lang.package.getResourceString("!error.buffer-too-large"));
}
Array.copy(vmethods, 0, vmethods = new Callable[vlength << 1 | 1], 0, vlength);
}
(vmethods[vlength] = callable).setVirtualIndex(vlength++);
break;
}
}
}
}
vmethods.length = vlength;
fldVirtualCallables = vmethods;
}
/* разметка таблицы сервисных методов */
if(isService())
{
int slength = 0;
Callable[] smethods = new Callable[0x0f];
for(int mindex = 0; mindex < mlength; mindex++)
{
Member member = members[mindex];
if(!member.isStatic() && member instanceof Callable && member.visibility > PRIVATE && !member.isFinal() && !member.isSpecial())
{
if(slength == smethods.capacity) Array.copy(smethods, 0, smethods = new Callable[slength << 1 | 1], 0, slength);
(smethods[slength] = (Callable) member).setServiceIndex(slength++);
}
}
smethods.length = slength;
fldServiceCallables = smethods;
}
}
public final void markupStruct() {
if(isHelper()) return;
int structSize = 0;
ClassType superclass = fldSuperclassType;
if(superclass != null && superclass.isStruct())
{
if(!superclass.fldStructMarked)
{
throw new IllegalClassTypeStateException(package.getResourceString("superclass.has-no-markup"));
}
structSize = superclass.fldStructSize;
}
/* разметка структуры */
if(isStruct())
{
for(int mlength = length, int mindex = 0; mindex < mlength; mindex++)
{
Member member = (Member) super.operator [](mindex);
if(!member.isStatic() && member instanceof AllocatableMember)
{
AllocatableMember allocatable = (AllocatableMember) member;
if(allocatable.parentNested == null)
{
int offsetAfter = allocatable.computeStructOffset(structSize);
if(structSize < offsetAfter) structSize = offsetAfter;
}
}
}
fldStructMarked = true;
fldStructSize = structSize;
}
}
public final boolean hasNativeCallables() { return fldNativeCallablesCounter > 0; }
public final boolean isSuperclass(ClassType type) {
if(type == null)
{
throw new NullPointerException(String.format(avt.lang.package.getResourceString("null-pointer.argument"), new Object[] { "type" }));
}
if(type.parentProgramme != parentProgramme)
{
throw new IllegalArgumentException(package.getResourceString("type.not-same-programme.type"));
}
for(ClassType current = fldSuperclassType; current != null; current = current.fldSuperclassType) if(type == current)
{
return true;
}
return false;
}
public final boolean isSuperclass(String specialCanonicalName) {
if(specialCanonicalName != null && !specialCanonicalName.isEmpty())
{
for(ClassType current = fldSuperclassType; current != null; current = current.fldSuperclassType) if(specialCanonicalName.equals(current.specialCanonicalName)) return true;
}
return false;
}
public final boolean isSuperservice(ClassType type) {
if(type == null)
{
throw new NullPointerException(String.format(avt.lang.package.getResourceString("null-pointer.argument"), new Object[] { "type" }));
}
if(type.parentProgramme != parentProgramme)
{
throw new IllegalArgumentException(package.getResourceString("type.not-same-programme.type"));
}
return Array.indexOf(type, fldSuperservicesTypes, 0, fldSuperservicesLength) >= 0;
}
public final boolean isSuperservice(String specialCanonicalName) {
if(specialCanonicalName != null && !specialCanonicalName.isEmpty())
{
for(ClassType[] types = fldSuperservicesTypes, int index = fldSuperservicesLength; index-- > 0; ) if(specialCanonicalName.equals(types[index].specialCanonicalName)) return true;
}
return false;
}
public final int getHelperForPosition() { return fldHelperForPosition; }
public final int getSuperclassPosition() { return fldSuperclassPosition; }
public final int getSuperservicesLength() { return fldSuperservicesLength; }
public final int getSuperservicePositionAt(int index) {
if(fldSuperservicesLength <= 0)
{
throw new ArrayIndexOutOfBoundsException(avt.lang.package.getResourceString("out-of-bounds.array-index"));
}
return fldSuperservicesPositions[index];
}
public final int getSuperserviceIndex(ClassType type) {
if(type == null)
{
throw new NullPointerException(String.format(avt.lang.package.getResourceString("null-pointer.argument"), new Object[] { "type" }));
}
if(type.parentProgramme != parentProgramme)
{
throw new IllegalArgumentException(package.getResourceString("type.not-same-programme.type"));
}
return Array.indexOf(type, fldSuperservicesTypes, 0, fldSuperservicesLength);
}
public final Callable[] virtualCallables() {
Callable[] result = fldVirtualCallables;
if(result == null) return null;
int length = result.length;
Array.copy(result, 0, result = new Callable[length], 0, length);
return result;
}
public final Callable[] serviceCallables() {
Callable[] result = fldServiceCallables;
if(result == null) return null;
int length = result.length;
Array.copy(result, 0, result = new Callable[length], 0, length);
return result;
}
public final Fieldoid[] findFieldoids(String specialSimpleName, ClassType areVisibleFrom) {
if(specialSimpleName == null)
{
throw new NullPointerException(String.format(avt.lang.package.getResourceString("null-pointer.argument"), new Object[] { "specialSimpleName" }));
}
specialSimpleName = specialSimpleName.intern();
ClassType place = fldHelperForType;
if(place == null)
{
place = this;
}
if(areVisibleFrom == null)
{
areVisibleFrom = place;
}
else if(areVisibleFrom.parentProgramme != parentProgramme)
{
throw new IllegalArgumentException(package.getResourceString("visibility-type.not-same-programme"));
}
/* поиск полеоида в этом типе и его суперклассах, с учётом видимости */
{
Fieldoid found0 = null;
Fieldoid found1 = null;
ClassType current = place;
label0: do
{
for(ClassType[] helpers = current.fldHelpers.array, int hlength = helpers.length, int hindex = -1; hindex < hlength; hindex++)
{
ClassType container = hindex < 0 ? current : helpers[hindex];
if(current == container || areVisibleFrom.source.contains(container) && container.isVisibleFrom(areVisibleFrom))
{
Member member = container.getChildMember(specialSimpleName);
if(member instanceof Fieldoid && member.isVisibleFrom(areVisibleFrom, this))
{
if(found0 != null)
{
if(!container.isHelper() && !found0.parentType.isHelper())
{
return new Fieldoid[] { found0 };
}
found1 = (Fieldoid) member;
break label0;
}
found0 = (Fieldoid) member;
}
}
}
} while((current = current.fldSuperclassType) != null);
if(found0 != null)
{
return found1 == null ? new Fieldoid[] { found0 } : new Fieldoid[] { found0, found1 };
}
}
/* поиск полеоидов в суперсервисах, с учётом видимости */
{
Fieldoid found0 = null;
Fieldoid found1 = null;
label0: for(ClassType[] types = place.fldSuperservicesTypes, int tlength = place.fldSuperservicesLength, int tindex = 0; tindex < tlength; tindex++)
{
ClassType current = types[tindex];
for(ClassType[] helpers = current.fldHelpers.array, int hlength = helpers.length, int hindex = -1; hindex < hlength; hindex++)
{
ClassType container = hindex < 0 ? current : helpers[hindex];
if(current == container || areVisibleFrom.source.contains(container) && container.isVisibleFrom(areVisibleFrom))
{
Member member = container.getChildMember(specialSimpleName);
if(member instanceof Fieldoid && member.isVisibleFrom(areVisibleFrom, this))
{
if(found0 != null)
{
found1 = (Fieldoid) member;
break label0;
}
found0 = (Fieldoid) member;
}
}
}
}
if(found0 != null)
{
return found1 == null ? new Fieldoid[] { found0 } : new Fieldoid[] { found0, found1 };
}
}
/* поиск полеоида в этом типе и его супертипах, без учёта видимости */
{
int tindex = -1;
int tlength = place.fldSuperservicesLength;
ClassType[] types = place.fldSuperservicesTypes;
ClassType current = place;
do
{
for(ClassType[] helpers = current.fldHelpers.array, int hlength = helpers.length, int hindex = -1; hindex < hlength; hindex++)
{
ClassType container = hindex < 0 ? current : helpers[hindex];
if(current == container || areVisibleFrom.source.contains(container) && container.isVisibleFrom(areVisibleFrom))
{
Member member = container.getChildMember(specialSimpleName);
if(member instanceof Fieldoid)
{
return new Fieldoid[] { (Fieldoid) member };
}
}
}
if(tindex < 0 && (current = current.fldSuperclassType) == null)
{
tindex = 0;
}
if(tindex >= 0)
{
current = tindex >= tlength ? null : types[tindex];
tindex++;
}
} while(current != null);
}
return null;
}
public final Callable[] findInterrupts(String specialSimpleName, ClassType areVisibleFrom) {
if(specialSimpleName == null)
{
throw new NullPointerException(String.format(avt.lang.package.getResourceString("null-pointer.argument"), new Object[] { "specialSimpleName" }));
}
specialSimpleName = specialSimpleName.intern();
ClassType place = fldHelperForType;
if(place == null)
{
place = this;
}
if(areVisibleFrom == null)
{
areVisibleFrom = place;
}
else if(areVisibleFrom.parentProgramme != parentProgramme)
{
throw new IllegalArgumentException(package.getResourceString("visibility-type.not-same-programme"));
}
Callable callable;
/* поиск прерывания в этом типе и его суперклассах, с учётом видимости */
{
Callable found0 = null;
Callable found1 = null;
ClassType current = place;
label0: do
{
for(ClassType[] helpers = current.fldHelpers.array, int hlength = helpers.length, int hindex = -1; hindex < hlength; hindex++)
{
ClassType container = hindex < 0 ? current : helpers[hindex];
if(current == container || areVisibleFrom.source.contains(container) && container.isVisibleFrom(areVisibleFrom))
{
Member member = container.getChildMember(specialSimpleName);
if(member instanceof Callable && (callable = (Callable) member).isInterrupt() && member.isVisibleFrom(areVisibleFrom, this))
{
if(found0 != null)
{
if(!container.isHelper() && !found0.parentType.isHelper())
{
return new Callable[] { found0 };
}
found1 = callable;
break label0;
}
found0 = callable;
}
}
}
} while((current = current.fldSuperclassType) != null);
if(found0 != null)
{
return found1 == null ? new Callable[] { found0 } : new Callable[] { found0, found1 };
}
}
/* поиск прерываний в суперсервисах, с учётом видимости */
{
Callable found0 = null;
Callable found1 = null;
label0: for(ClassType[] types = place.fldSuperservicesTypes, int tlength = place.fldSuperservicesLength, int tindex = 0; tindex < tlength; tindex++)
{
ClassType current = types[tindex];
for(ClassType[] helpers = current.fldHelpers.array, int hlength = helpers.length, int hindex = -1; hindex < hlength; hindex++)
{
ClassType container = hindex < 0 ? current : helpers[hindex];
if(current == container || areVisibleFrom.source.contains(container) && container.isVisibleFrom(areVisibleFrom))
{
Member member = container.getChildMember(specialSimpleName);
if(member instanceof Callable && (callable = (Callable) member).isInterrupt() && member.isVisibleFrom(areVisibleFrom, this))
{
if(found0 != null)
{
found1 = callable;
break label0;
}
found0 = callable;
}
}
}
}
if(found0 != null)
{
return found1 == null ? new Callable[] { found0 } : new Callable[] { found0, found1 };
}
}
/* поиск прерывания в этом типе и его супертипах, без учёта видимости */
{
int tindex = -1;
int tlength = place.fldSuperservicesLength;
ClassType[] types = place.fldSuperservicesTypes;
ClassType current = place;
do
{
for(ClassType[] helpers = current.fldHelpers.array, int hlength = helpers.length, int hindex = -1; hindex < hlength; hindex++)
{
ClassType container = hindex < 0 ? current : helpers[hindex];
if(current == container || areVisibleFrom.source.contains(container) && container.isVisibleFrom(areVisibleFrom))
{
Member member = container.getChildMember(specialSimpleName);
if(member instanceof Callable && (callable = (Callable) member).isInterrupt())
{
return new Callable[] { callable };
}
}
}
if(tindex < 0 && (current = current.fldSuperclassType) == null)
{
tindex = 0;
}
if(tindex >= 0)
{
current = tindex >= tlength ? null : types[tindex];
tindex++;
}
} while(current != null);
}
return null;
}
public final InstInit[] findConstructors(Type[] arguments, ClassType areVisibleFrom) {
if(areVisibleFrom == null)
{
areVisibleFrom = this;
}
else if(areVisibleFrom.parentProgramme != parentProgramme)
{
throw new IllegalArgumentException(package.getResourceString("visibility-type.not-same-programme"));
}
if(isHelper())
{
return null;
}
InstInit constructor;
/* определение места поиска конструкторов */
ClassType current = this;
while(!current.isClass()) if((current = current.fldSuperclassType) == null)
{
return null;
}
/* первый конструктор */
ProgrammeItem first = current.getChildMember(SPECNAME_INST_INIT);
/* поиск конструктора с точно совпадающими типами аргументов и с учётом видимости */
for(ProgrammeItem member = first; member != null; member = member.nextItem)
{
if(member instanceof InstInit && (constructor = (InstInit) member).isVisibleFrom(areVisibleFrom, this) && constructor.isIdentityArguments(arguments))
{
return new InstInit[] { constructor };
}
}
/* поиск конструкторов с конвертируемыми типами аргументов и с учётом видимости */
{
InstInit found0 = null;
InstInit found1 = null;
for(ProgrammeItem member = first; member != null; member = member.nextItem)
{
if(member instanceof InstInit && (constructor = (InstInit) member).isVisibleFrom(areVisibleFrom, this) && constructor.isConvertableArguments(arguments))
{
if(found0 != null)
{
found1 = constructor;
break;
}
found0 = constructor;
}
}
if(found0 != null)
{
return found1 == null ? new InstInit[] { found0 } : new InstInit[] { found0, found1 };
}
}
/* поиск конструктора с точно совпадающими типами аргументов и без учёта видимости */
for(ProgrammeItem member = first; member != null; member = member.nextItem)
{
if(member instanceof InstInit && (constructor = (InstInit) member).isIdentityArguments(arguments))
{
return new InstInit[] { constructor };
}
}
/* поиск конструкторов с конвертируемыми типами аргументов и без учёта видимости */
{
InstInit found0 = null;
InstInit found1 = null;
for(ProgrammeItem member = first; member != null; member = member.nextItem)
{
if(member instanceof InstInit && (constructor = (InstInit) member).isConvertableArguments(arguments))
{
if(found0 != null)
{
found1 = constructor;
break;
}
found0 = constructor;
}
}
if(found0 != null)
{
return found1 == null ? new InstInit[] { found0 } : new InstInit[] { found0, found1 };
}
}
/* поиск конструктора с любыми типами аргументов и без учёта видимости */
return !(first instanceof InstInit) ? null : new InstInit[] { (InstInit) first };
}
public final Method[] findMethods(String specialSimpleName, Type[] arguments, ClassType areVisibleFrom) {
if(specialSimpleName == null)
{
throw new NullPointerException(String.format(avt.lang.package.getResourceString("null-pointer.argument"), new Object[] { "specialSimpleName" }));
}
specialSimpleName = specialSimpleName.intern();
ClassType place = fldHelperForType;
if(place == null)
{
place = this;
}
if(areVisibleFrom == null)
{
areVisibleFrom = place;
}
else if(areVisibleFrom.parentProgramme != parentProgramme)
{
throw new IllegalArgumentException(package.getResourceString("visibility-type.not-same-programme"));
}
int tlength = place.fldSuperservicesLength;
ClassType[] types = place.fldSuperservicesTypes;
Method callable;
/* поиск метода в этом типе и его супертипах, с точно совпадающими типами аргументов и с учётом видимости */
{
int tindex = -1;
Method found0 = null;
Method found1 = null;
ClassType current = place;
label0: do
{
for(ClassType[] helpers = current.fldHelpers.array, int hlength = helpers.length, int hindex = -1; hindex < hlength; hindex++)
{
ClassType container = hindex < 0 ? current : helpers[hindex];
if(current == container || areVisibleFrom.source.contains(container) && container.isVisibleFrom(areVisibleFrom))
{
for(ProgrammeItem member = container.getChildMember(specialSimpleName); member != null; member = member.nextItem)
{
if(member instanceof Method && (callable = (Method) member).isVisibleFrom(areVisibleFrom, this) && callable.isIdentityArguments(arguments))
{
if(found0 == null)
{
found0 = callable;
continue;
}
if(!found0.isIdentityArguments(callable) || container.isHelper() || found0.parentType.isHelper())
{
found1 = callable;
break label0;
}
}
}
}
}
if(tindex < 0 && (current = current.fldSuperclassType) == null)
{
tindex = 0;
}
if(tindex >= 0)
{
current = tindex >= tlength ? null : types[tindex];
tindex++;
}
} while(current != null);
if(found0 != null)
{
return found1 == null ? new Method[] { found0 } : new Method[] { found0, found1 };
}
}
/* поиск методов в этом типе и его супертипах, с конвертируемыми типами аргументов и с учётом видимости */
{
int tindex = -1;
Method found0 = null;
Method found1 = null;
ClassType current = place;
label0: do
{
for(ClassType[] helpers = current.fldHelpers.array, int hlength = helpers.length, int hindex = -1; hindex < hlength; hindex++)
{
ClassType container = hindex < 0 ? current : helpers[hindex];
if(current == container || areVisibleFrom.source.contains(container) && container.isVisibleFrom(areVisibleFrom))
{
for(ProgrammeItem member = container.getChildMember(specialSimpleName); member != null; member = member.nextItem)
{
if(member instanceof Method && (callable = (Method) member).isVisibleFrom(areVisibleFrom, this) && callable.isConvertableArguments(arguments))
{
if(found0 == null)
{
found0 = callable;
continue;
}
if(!found0.isIdentityArguments(callable) || container.isHelper() || found0.parentType.isHelper())
{
found1 = callable;
break label0;
}
}
}
}
}
if(tindex < 0 && (current = current.fldSuperclassType) == null)
{
tindex = 0;
}
if(tindex >= 0)
{
current = tindex >= tlength ? null : types[tindex];
tindex++;
}
} while(current != null);
if(found0 != null)
{
return found1 == null ? new Method[] { found0 } : new Method[] { found0, found1 };
}
}
/* поиск метода в этом типе и его супертипах, с точно совпадающими типами аргументов и без учёта видимости */
{
int tindex = -1;
Method found0 = null;
Method found1 = null;
ClassType current = place;
label0: do
{
for(ClassType[] helpers = current.fldHelpers.array, int hlength = helpers.length, int hindex = -1; hindex < hlength; hindex++)
{
ClassType container = hindex < 0 ? current : helpers[hindex];
if(current == container || areVisibleFrom.source.contains(container) && container.isVisibleFrom(areVisibleFrom))
{
for(ProgrammeItem member = container.getChildMember(specialSimpleName); member != null; member = member.nextItem)
{
if(member instanceof Method && (callable = (Method) member).isIdentityArguments(arguments))
{
if(found0 == null)
{
found0 = callable;
continue;
}
if(!found0.isIdentityArguments(callable) || container.isHelper() || found0.parentType.isHelper())
{
found1 = callable;
break label0;
}
}
}
}
}
if(tindex < 0 && (current = current.fldSuperclassType) == null)
{
tindex = 0;
}
if(tindex >= 0)
{
current = tindex >= tlength ? null : types[tindex];
tindex++;
}
} while(current != null);
if(found0 != null)
{
return found1 == null ? new Method[] { found0 } : new Method[] { found0, found1 };
}
}
/* поиск методов в этом типе и его супертипах, с конвертируемыми типами аргументов и без учёта видимости */
{
int tindex = -1;
Method found0 = null;
Method found1 = null;
ClassType current = place;
label0: do
{
for(ClassType[] helpers = current.fldHelpers.array, int hlength = helpers.length, int hindex = -1; hindex < hlength; hindex++)
{
ClassType container = hindex < 0 ? current : helpers[hindex];
if(current == container || areVisibleFrom.source.contains(container) && container.isVisibleFrom(areVisibleFrom))
{
for(ProgrammeItem member = container.getChildMember(specialSimpleName); member != null; member = member.nextItem)
{
if(member instanceof Method && (callable = (Method) member).isConvertableArguments(arguments))
{
if(found0 == null)
{
found0 = callable;
continue;
}
if(!found0.isIdentityArguments(callable) || container.isHelper() || found0.parentType.isHelper())
{
found1 = callable;
break label0;
}
}
}
}
}
if(tindex < 0 && (current = current.fldSuperclassType) == null)
{
tindex = 0;
}
if(tindex >= 0)
{
current = tindex >= tlength ? null : types[tindex];
tindex++;
}
} while(current != null);
if(found0 != null)
{
return found1 == null ? new Method[] { found0 } : new Method[] { found0, found1 };
}
}
/* поиск методов в этом типе и его супертипах, с любыми типами аргументов и без учёта видимости */
{
int tindex = -1;
ClassType current = place;
do
{
for(ClassType[] helpers = current.fldHelpers.array, int hlength = helpers.length, int hindex = -1; hindex < hlength; hindex++)
{
ClassType container = hindex < 0 ? current : helpers[hindex];
if(current == container || areVisibleFrom.source.contains(container) && container.isVisibleFrom(areVisibleFrom))
{
for(ProgrammeItem member = container.getChildMember(specialSimpleName); member != null; member = member.nextItem) if(member instanceof Method)
{
return new Method[] { (Method) member };
}
}
}
if(tindex < 0 && (current = current.fldSuperclassType) == null)
{
tindex = 0;
}
if(tindex >= 0)
{
current = tindex >= tlength ? null : types[tindex];
tindex++;
}
} while(current != null);
}
return null;
}
public final Operator[] findOperators(int kind, Type[] arguments, ClassType areVisibleFrom) {
String specialSimpleName = Operator.kindToSpecialSimpleName(kind);
ClassType place = fldHelperForType;
if(place == null)
{
place = this;
}
if(areVisibleFrom == null)
{
areVisibleFrom = place;
}
else if(areVisibleFrom.parentProgramme != parentProgramme)
{
throw new IllegalArgumentException(package.getResourceString("visibility-type.not-same-programme"));
}
int tlength = place.fldSuperservicesLength;
ClassType[] types = place.fldSuperservicesTypes;
Operator callable;
/* поиск оператора в этом типе и его супертипах, с точно совпадающими типами аргументов и с учётом видимости */
{
int tindex = -1;
Operator found0 = null;
Operator found1 = null;
ClassType current = place;
label0: do
{
for(ClassType[] helpers = current.fldHelpers.array, int hlength = helpers.length, int hindex = -1; hindex < hlength; hindex++)
{
ClassType container = hindex < 0 ? current : helpers[hindex];
if(current == container || areVisibleFrom.source.contains(container) && container.isVisibleFrom(areVisibleFrom))
{
for(ProgrammeItem member = container.getChildMember(specialSimpleName); member != null; member = member.nextItem)
{
if(member instanceof Operator && (callable = (Operator) member).isVisibleFrom(areVisibleFrom, this) && callable.isIdentityArguments(arguments))
{
if(found0 == null)
{
found0 = callable;
continue;
}
if(!found0.isIdentityArguments(callable) || container.isHelper() || found0.parentType.isHelper())
{
found1 = callable;
break label0;
}
}
}
}
}
if(tindex < 0 && (current = current.fldSuperclassType) == null)
{
tindex = 0;
}
if(tindex >= 0)
{
current = tindex >= tlength ? null : types[tindex];
tindex++;
}
} while(current != null);
if(found0 != null)
{
return found1 == null ? new Operator[] { found0 } : new Operator[] { found0, found1 };
}
}
/* поиск операторов в этом типе и его супертипах, с конвертируемыми типами аргументов и с учётом видимости */
{
int tindex = -1;
Operator found0 = null;
Operator found1 = null;
ClassType current = place;
label0: do
{
for(ClassType[] helpers = current.fldHelpers.array, int hlength = helpers.length, int hindex = -1; hindex < hlength; hindex++)
{
ClassType container = hindex < 0 ? current : helpers[hindex];
if(current == container || areVisibleFrom.source.contains(container) && container.isVisibleFrom(areVisibleFrom))
{
for(ProgrammeItem member = container.getChildMember(specialSimpleName); member != null; member = member.nextItem)
{
if(member instanceof Operator && (callable = (Operator) member).isVisibleFrom(areVisibleFrom, this) && callable.isConvertableArguments(arguments))
{
if(found0 == null)
{
found0 = callable;
continue;
}
if(!found0.isIdentityArguments(callable) || container.isHelper() || found0.parentType.isHelper())
{
found1 = callable;
break label0;
}
}
}
}
}
if(tindex < 0 && (current = current.fldSuperclassType) == null)
{
tindex = 0;
}
if(tindex >= 0)
{
current = tindex >= tlength ? null : types[tindex];
tindex++;
}
} while(current != null);
if(found0 != null)
{
return found1 == null ? new Operator[] { found0 } : new Operator[] { found0, found1 };
}
}
/* поиск оператора в этом типе и его супертипах, с точно совпадающими типами аргументов и без учёта видимости */
{
int tindex = -1;
Operator found0 = null;
Operator found1 = null;
ClassType current = place;
label0: do
{
for(ClassType[] helpers = current.fldHelpers.array, int hlength = helpers.length, int hindex = -1; hindex < hlength; hindex++)
{
ClassType container = hindex < 0 ? current : helpers[hindex];
if(current == container || areVisibleFrom.source.contains(container) && container.isVisibleFrom(areVisibleFrom))
{
for(ProgrammeItem member = container.getChildMember(specialSimpleName); member != null; member = member.nextItem)
{
if(member instanceof Operator && (callable = (Operator) member).isIdentityArguments(arguments))
{
if(found0 == null)
{
found0 = callable;
continue;
}
if(!found0.isIdentityArguments(callable) || container.isHelper() || found0.parentType.isHelper())
{
found1 = callable;
break label0;
}
}
}
}
}
if(tindex < 0 && (current = current.fldSuperclassType) == null)
{
tindex = 0;
}
if(tindex >= 0)
{
current = tindex >= tlength ? null : types[tindex];
tindex++;
}
} while(current != null);
if(found0 != null)
{
return found1 == null ? new Operator[] { found0 } : new Operator[] { found0, found1 };
}
}
/* поиск операторов в этом типе и его супертипах, с конвертируемыми типами аргументов и без учёта видимости */
{
int tindex = -1;
Operator found0 = null;
Operator found1 = null;
ClassType current = place;
label0: do
{
for(ClassType[] helpers = current.fldHelpers.array, int hlength = helpers.length, int hindex = -1; hindex < hlength; hindex++)
{
ClassType container = hindex < 0 ? current : helpers[hindex];
if(current == container || areVisibleFrom.source.contains(container) && container.isVisibleFrom(areVisibleFrom))
{
for(ProgrammeItem member = container.getChildMember(specialSimpleName); member != null; member = member.nextItem)
{
if(member instanceof Operator && (callable = (Operator) member).isConvertableArguments(arguments))
{
if(found0 == null)
{
found0 = callable;
continue;
}
if(!found0.isIdentityArguments(callable) || container.isHelper() || found0.parentType.isHelper())
{
found1 = callable;
break label0;
}
}
}
}
}
if(tindex < 0 && (current = current.fldSuperclassType) == null)
{
tindex = 0;
}
if(tindex >= 0)
{
current = tindex >= tlength ? null : types[tindex];
tindex++;
}
} while(current != null);
if(found0 != null)
{
return found1 == null ? new Operator[] { found0 } : new Operator[] { found0, found1 };
}
}
/* поиск операторов в этом типе и его супертипах, с любыми типами аргументов и без учёта видимости */
{
int tindex = -1;
ClassType current = place;
do
{
for(ClassType[] helpers = current.fldHelpers.array, int hlength = helpers.length, int hindex = -1; hindex < hlength; hindex++)
{
ClassType container = hindex < 0 ? current : helpers[hindex];
if(current == container || areVisibleFrom.source.contains(container) && container.isVisibleFrom(areVisibleFrom))
{
for(ProgrammeItem member = container.getChildMember(specialSimpleName); member != null; member = member.nextItem) if(member instanceof Operator)
{
return new Operator[] { (Operator) member };
}
}
}
if(tindex < 0 && (current = current.fldSuperclassType) == null)
{
tindex = 0;
}
if(tindex >= 0)
{
current = tindex >= tlength ? null : types[tindex];
tindex++;
}
} while(current != null);
}
return null;
}
public final Member resolveName(String specialSimpleName, ClassType isVisibleFrom, boolean isVisibleOnly) {
if(specialSimpleName == null)
{
throw new NullPointerException(String.format(avt.lang.package.getResourceString("null-pointer.argument"), new Object[] { "specialSimpleName" }));
}
ClassType place = fldHelperForType;
if(place == null)
{
place = this;
}
if(isVisibleFrom == null)
{
isVisibleFrom = place;
}
else if(isVisibleFrom.parentProgramme != parentProgramme)
{
throw new IllegalArgumentException(package.getResourceString("visibility-type.not-same-programme"));
}
int tlength = place.fldSuperservicesLength;
ClassType[] types = place.fldSuperservicesTypes;
/* поиск члена в этом типе и его супертипах, с учётом видимости */
{
int tindex = -1;
ClassType current = place;
do
{
for(ClassType[] helpers = current.fldHelpers.array, int hlength = helpers.length, int hindex = -1; hindex < hlength; hindex++)
{
ClassType container = hindex < 0 ? current : helpers[hindex];
if(current == container || isVisibleFrom.source.contains(container) && container.isVisibleFrom(isVisibleFrom))
{
for(Member member = container.getChildMember(specialSimpleName); member != null; member = (Member) member.nextItem)
{
if(member.isVisibleFrom(isVisibleFrom, this)) return member;
}
}
}
if(tindex < 0 && (current = current.fldSuperclassType) == null)
{
tindex = 0;
}
if(tindex >= 0)
{
current = tindex >= tlength ? null : types[tindex];
tindex++;
}
} while(current != null);
}
/* поиск члена в этом типе и его супертипах, без учёта видимости */
if(!isVisibleOnly)
{
int tindex = -1;
ClassType current = place;
do
{
for(ClassType[] helpers = current.fldHelpers.array, int hlength = helpers.length, int hindex = -1; hindex < hlength; hindex++)
{
ClassType container = hindex < 0 ? current : helpers[hindex];
if(current == container || isVisibleFrom.source.contains(container) && container.isVisibleFrom(isVisibleFrom))
{
Member member = container.getChildMember(specialSimpleName);
if(member != null) return member;
}
}
if(tindex < 0 && (current = current.fldSuperclassType) == null)
{
tindex = 0;
}
if(tindex >= 0)
{
current = tindex >= tlength ? null : types[tindex];
tindex++;
}
} while(current != null);
}
return null;
}
public final Member getChildMember(String specialSimpleName) { return (Member) super.getChildItem(specialSimpleName); }
public final Member getChildMember(String specialSimpleName, boolean ignoreCase) { return (Member) super.getChildItem(specialSimpleName, ignoreCase); }
public final Callable getChildCallable(String specialSimpleName, Type[] arguments) {
for(ProgrammeItem member = super.getChildItem(specialSimpleName); member != null; member = member.nextItem) if(member instanceof Callable)
{
Callable callable = (Callable) member;
if(callable.isIdentityArguments(arguments)) return callable;
}
return null;
}
public final Callable getChildCallable(String specialSimpleName, TypedItem[] arguments) {
for(ProgrammeItem member = super.getChildItem(specialSimpleName); member != null; member = member.nextItem) if(member instanceof Callable)
{
Callable callable = (Callable) member;
if(callable.isIdentityArguments(arguments)) return callable;
}
return null;
}
public final Fieldoid getChildFieldoid(String specialSimpleName) {
for(ProgrammeItem member = super.getChildItem(specialSimpleName); member != null; member = member.nextItem) if(member instanceof Fieldoid)
{
return (Fieldoid) member;
}
return null;
}
public final InstInit getDefaultConstructor() { return fldDefaultConstructor; }
public final ClassInit getStaticBlock() { return fldStaticBlock; }
public final ClassType getHelperForType() { return fldHelperForType; }
public final ClassType getSuperclassType() { return fldSuperclassType; }
public final ClassType getSuperserviceTypeAt(int index) {
if(index < 0 || index >= fldSuperservicesLength)
{
throw new ArrayIndexOutOfBoundsException(avt.lang.package.getResourceString("out-of-bounds.array-index"));
}
return fldSuperservicesTypes[index];
}
public final int structSize { read = fldStructSize }
public final int instanceSize { read = fldInstanceSize }
public final String outputPath { read = fldOutputPath }
public final Member operator [](int index) { return (Member) super.operator [](index); }
protected void insertChildItem(ProgrammeItem item, int position) {
if(item != null && !(item instanceof Member))
{
throw new IllegalArgumentException(package.getResourceString("adding-item.not-a-member"));
}
super.insertChildItem(item, position);
if(item instanceof Callable && ((Callable) item).isNative())
{
fldNativeCallablesCounter++;
}
if(item instanceof ClassInit)
{
fldStaticBlock = (ClassInit) item;
}
else if(item instanceof InstInit)
{
InstInit constructor = (InstInit) item;
if(constructor.arguments.length <= 0) fldDefaultConstructor = constructor;
}
}
protected void removeChildItem(ProgrammeItem item) {
if(item instanceof Callable && ((Callable) item).isNative())
{
fldNativeCallablesCounter--;
}
if(fldStaticBlock == item)
{
fldStaticBlock = null;
}
else if(fldDefaultConstructor == item)
{
fldDefaultConstructor = null;
}
super.removeChildItem(item);
}
protected ReferenceType getCommonType(ReferenceType anot) { return isAssignableFrom(anot) ? this : anot.isAssignableFrom(this) ? anot : null; }
protected String composeRecompilableName() { return "L" + specialCanonicalName; }
protected String composeFasmSimpleName() { return specialCanonicalName; }
protected String composeFasmFullName() { return specialCanonicalName; }
protected String composeFasmFileName() { return specialSimpleName; }
package final void initSubtypes() {
Programme programme = parentProgramme;
ClassType superclass = fldSuperclassType;
int count = programme.classes.length + programme.arrays.length;
int index = 0;
if(superclass != null) do
{
if(index++ >= count)
{
throw new IllegalClassTypeStateException(package.getResourceString("class-type.!error.init-subtypes"));
}
ClassTypeArray stypes = superclass.fldSubtypes;
if(stypes != null) stypes.append(this);
} while((superclass = superclass.fldSuperclassType) != null);
}
package final Local thisArgument { read = fldThisArgument }
private ClassType[] getSubtypesStore() {
ClassTypeArray stypes = fldSubtypes;
return stypes == null ? null : stypes.array;
}
private Local createThisArgument() {
Programme programme = parentProgramme;
Local result = programme == null ? null : programme.newLocal(true, this, SPECNAME_THIS, null, null, -1);
if(result == null) result = new Local(true, this, SPECNAME_THIS, null, null, -1);
return result;
}
}