/*
Компилятор языка программирования
Объектно-ориентированный продвинутый векторный транслятор
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 }
}