use of org.develnext.jphp.core.tokenizer.token.expr.value.StaticAccessExprToken in project jphp by jphp-compiler.
the class TokenizerTest method testBraces.
@Test
public void testBraces() throws IOException {
Tokenizer tokenizer = new Tokenizer(new Context(" :: ->foobar('a', 1, 3.0);"));
assertTrue(tokenizer.nextToken() instanceof StaticAccessExprToken);
assertTrue(tokenizer.nextToken() instanceof DynamicAccessExprToken);
assertTrue(tokenizer.nextToken() instanceof NameToken);
assertTrue(tokenizer.nextToken() instanceof BraceExprToken);
assertTrue(tokenizer.nextToken() instanceof StringExprToken);
assertTrue(tokenizer.nextToken() instanceof CommaToken);
assertTrue(tokenizer.nextToken() instanceof IntegerExprToken);
assertTrue(tokenizer.nextToken() instanceof CommaToken);
assertTrue(tokenizer.nextToken() instanceof DoubleExprToken);
assertTrue(tokenizer.nextToken() instanceof BraceExprToken);
assertTrue(tokenizer.nextToken() instanceof SemicolonToken);
}
use of org.develnext.jphp.core.tokenizer.token.expr.value.StaticAccessExprToken in project jphp by jphp-compiler.
the class ClassStmtCompiler method writeInitEnvironment.
@SuppressWarnings("unchecked")
protected void writeInitEnvironment() {
if (!dynamicConstants.isEmpty() || !dynamicProperties.isEmpty()) {
initDynamicExists = true;
MethodNode node = new MethodNodeImpl();
node.access = ACC_STATIC + ACC_PUBLIC;
node.name = "__$initEnvironment";
node.desc = Type.getMethodDescriptor(Type.getType(void.class), Type.getType(Environment.class));
if (entity.isTrait()) {
node.desc = Type.getMethodDescriptor(Type.getType(void.class), Type.getType(Environment.class), Type.getType(String.class));
}
MethodStmtCompiler methodCompiler = new MethodStmtCompiler(this, node);
ExpressionStmtCompiler expressionCompiler = new ExpressionStmtCompiler(methodCompiler, null);
methodCompiler.writeHeader();
LabelNode l0 = expressionCompiler.makeLabel();
methodCompiler.addLocalVariable("~env", l0, Environment.class);
if (entity.isTrait())
methodCompiler.addLocalVariable("~class_name", l0, String.class);
LocalVariable l_class = methodCompiler.addLocalVariable("~class", l0, ClassEntity.class);
expressionCompiler.writePushEnv();
if (entity.isTrait()) {
expressionCompiler.writeVarLoad("~class_name");
expressionCompiler.writePushDupLowerCase();
} else {
expressionCompiler.writePushConstString(entity.getName());
expressionCompiler.writePushConstString(entity.getLowerName());
}
expressionCompiler.writePushConstBoolean(false);
expressionCompiler.writeSysDynamicCall(Environment.class, "fetchClass", ClassEntity.class, String.class, String.class, Boolean.TYPE);
expressionCompiler.writeVarStore(l_class, false, false);
// corrects defination of constants
final List<ConstStmtToken.Item> first = new ArrayList<ConstStmtToken.Item>();
final Set<String> usedNames = new HashSet<String>();
final List<ConstStmtToken.Item> other = new ArrayList<ConstStmtToken.Item>();
for (ConstStmtToken.Item el : dynamicConstants) {
Token tk = el.value.getSingle();
if (tk instanceof StaticAccessExprToken) {
StaticAccessExprToken access = (StaticAccessExprToken) tk;
boolean self = false;
if (access.getClazz() instanceof SelfExprToken)
self = true;
else if (access.getClazz() instanceof FulledNameToken && ((FulledNameToken) access.getClazz()).getName().equalsIgnoreCase(entity.getName())) {
self = true;
}
if (self) {
String name = ((NameToken) access.getField()).getName();
if (usedNames.contains(el.getFulledName()))
first.add(0, el);
else
first.add(el);
usedNames.add(name);
continue;
}
}
if (usedNames.contains(el.getFulledName()))
first.add(0, el);
else
other.add(el);
}
other.addAll(0, first);
expressionCompiler.writePushEnv();
TraceInfo trace = entity.getTrace();
expressionCompiler.writePushTraceInfo(trace.getStartLine(), trace.getStartPosition());
expressionCompiler.writePushConstNull();
expressionCompiler.writePushConstNull();
expressionCompiler.writePushConstNull();
expressionCompiler.writePushConstString(entity.getName());
expressionCompiler.writePushDup();
if (!isSystem()) {
expressionCompiler.writeSysDynamicCall(Environment.class, "pushCall", CallStackItem.class, TraceInfo.class, IObject.class, Memory[].class, String.class, String.class, String.class);
expressionCompiler.writePopAll(1);
}
for (ConstStmtToken.Item el : other) {
expressionCompiler.writeVarLoad(l_class);
expressionCompiler.writePushEnv();
expressionCompiler.writePushConstString(el.getFulledName());
expressionCompiler.writeExpression(el.value, true, false, true);
expressionCompiler.writePopBoxing(true);
expressionCompiler.writeSysDynamicCall(ClassEntity.class, "addDynamicConstant", void.class, Environment.class, String.class, Memory.class);
}
for (ClassVarStmtToken el : dynamicProperties) {
expressionCompiler.writeVarLoad(l_class);
expressionCompiler.writePushEnv();
expressionCompiler.writePushConstString(el.getVariable().getName());
expressionCompiler.writeExpression(el.getValue(), true, false, true);
expressionCompiler.writePopBoxing(true);
expressionCompiler.writeSysDynamicCall(ClassEntity.class, el.isStatic() ? "addDynamicStaticProperty" : "addDynamicProperty", void.class, Environment.class, String.class, Memory.class);
}
if (!isSystem()) {
expressionCompiler.writePushEnv();
expressionCompiler.writeSysDynamicCall(Environment.class, "popCall", CallStackItem.class);
expressionCompiler.writePopAll(1);
}
node.instructions.add(new InsnNode(RETURN));
methodCompiler.writeFooter();
this.node.methods.add(node);
}
}
use of org.develnext.jphp.core.tokenizer.token.expr.value.StaticAccessExprToken in project jphp by jphp-compiler.
the class MethodStmtCompiler method compile.
@Override
public MethodEntity compile() {
if (statement != null) {
if (external)
statement.setDynamicLocal(true);
if (statement.getDocComment() != null)
entity.setDocComment(new DocumentComment(statement.getDocComment().getComment()));
entity.setAbstract(statement.isAbstract());
entity.setAbstractable(statement.getBody() == null);
entity.setFinal(statement.isFinal());
entity.setStatic(statement.isStatic());
entity.setModifier(statement.getModifier());
entity.setReturnReference(statement.isReturnReference());
entity.setTrace(statement.toTraceInfo(compiler.getContext()));
entity.setImmutable(statement.getArguments().isEmpty());
entity.setGeneratorEntity(generatorEntity);
if (statement.getReturnHintTypeClass() != null) {
entity.setReturnTypeChecker(TypeChecker.of(statement.getReturnHintTypeClass().getName()));
} else if (statement.getReturnHintType() != null) {
entity.setReturnTypeChecker(TypeChecker.of(statement.getReturnHintType()));
if (statement.getReturnHintType() == HintType.SELF) {
entity.setUsesStackTrace(true);
}
}
entity.setReturnTypeNullable(statement.isReturnOptional());
if (clazz.isSystem())
entity.setInternalName(entity.getName());
else
entity.setInternalName(entity.getName() + "$" + clazz.entity.nextMethodIndex());
ParameterEntity[] parameters = new ParameterEntity[statement.getArguments().size()];
int i = 0;
for (ArgumentStmtToken argument : statement.getArguments()) {
parameters[i] = new ParameterEntity(compiler.getContext());
ParameterEntity parameter = parameters[i];
parameter.setReference(argument.isReference());
parameter.setName(argument.getName().getName());
parameter.setTrace(argument.toTraceInfo(compiler.getContext()));
parameter.setNullable(argument.isOptional());
parameter.setMutable(statement.isDynamicLocal() || statement.variable(argument.getName()).isMutable());
parameter.setUsed(!statement.isUnusedVariable(argument.getName()));
parameter.setVariadic(argument.isVariadic());
parameter.setType(argument.getHintType());
if (argument.getHintTypeClass() != null) {
parameter.setTypeClass(argument.getHintTypeClass().getName());
}
ExpressionStmtCompiler expressionStmtCompiler = new ExpressionStmtCompiler(compiler);
ExprStmtToken value = argument.getValue();
if (value != null) {
Memory defaultValue = expressionStmtCompiler.writeExpression(value, true, true, false);
// try detect constant
if (value.isSingle()) {
if (value.getSingle() instanceof NameToken) {
parameter.setDefaultValueConstName(((NameToken) value.getSingle()).getName());
if (defaultValue == null) {
defaultValue = (new ConstantMemory(((NameToken) value.getSingle()).getName()));
parameter.setMutable(true);
}
} else if (value.getSingle() instanceof StaticAccessExprToken) {
StaticAccessExprToken access = (StaticAccessExprToken) value.getSingle();
if (access.getClazz() instanceof NameToken && access.getField() instanceof NameToken) {
if (defaultValue == null)
defaultValue = (new ClassConstantMemory(((NameToken) access.getClazz()).getName(), ((NameToken) access.getField()).getName()));
parameter.setDefaultValueConstName(((NameToken) access.getClazz()).getName() + "::" + ((NameToken) access.getField()).getName());
parameter.setMutable(true);
}
}
}
if (defaultValue == null)
compiler.getEnvironment().error(argument.toTraceInfo(compiler.getContext()), ErrorType.E_COMPILE_ERROR, Messages.ERR_EXPECTED_CONST_VALUE, "$" + argument.getName().getName());
parameter.setDefaultValue(defaultValue);
}
i++;
}
entity.setParameters(parameters);
}
if (statement != null && clazz.statement.isInterface()) {
if (!statement.isInterfacable()) {
compiler.getEnvironment().error(entity.getTrace(), Messages.ERR_INTERFACE_FUNCTION_CANNOT_CONTAIN_BODY.fetch(entity.getSignatureString(false)));
}
if (statement.isAbstract() || statement.isFinal()) {
compiler.getEnvironment().error(entity.getTrace(), Messages.ERR_ACCESS_TYPE_FOR_INTERFACE_METHOD.fetch(entity.getSignatureString(false)));
}
} else {
writeHeader();
if (statement.isGenerator()) {
entity.setEmpty(false);
entity.setImmutable(false);
entity.setResult(null);
GeneratorStmtCompiler generatorStmtCompiler = new GeneratorStmtCompiler(compiler, statement);
entity.setGeneratorEntity(generatorStmtCompiler.compile());
ExpressionStmtCompiler expr = new ExpressionStmtCompiler(this, null);
expr.makeUnknown(new TypeInsnNode(NEW, entity.getGeneratorEntity().getInternalName()));
expr.stackPush(Memory.Type.REFERENCE);
expr.writePushDup();
// env
expr.writePushEnv();
// classEntity
expr.writePushDup();
expr.writePushConstString(compiler.getModule().getInternalName());
expr.writePushConstInt((int) entity.getGeneratorEntity().getId());
expr.writeSysDynamicCall(Environment.class, "__getGenerator", ClassEntity.class, String.class, Integer.TYPE);
// self
expr.writePushThis();
// uses
expr.writeVarLoad("~args");
expr.writeSysCall(entity.getGeneratorEntity().getInternalName(), INVOKESPECIAL, Constants.INIT_METHOD, void.class, Environment.class, ClassEntity.class, Memory.class, Memory[].class);
expr.writeSysStaticCall(ObjectMemory.class, "valueOf", Memory.class, IObject.class);
expr.makeUnknown(new InsnNode(Opcodes.ARETURN));
expr.stackPop();
} else {
ExpressionStmtCompiler expr = new ExpressionStmtCompiler(this, null);
entity.setEmpty(true);
if (entity.getResult() == null) {
entity.setResult(Memory.UNDEFINED);
}
if (statement != null && statement.getBody() != null) {
expr.writeDefineVariables(statement.getLocal());
expr.write(statement.getBody());
if (!statement.getBody().getInstructions().isEmpty()) {
entity.setEmpty(false);
if (entity.getResult() != null && entity.getResult().isUndefined()) {
entity.setResult(null);
}
}
}
if (generatorEntity != null) {
expr.writeVarLoad(LocalVariable.THIS);
expr.writePushConstBoolean(false);
expr.writeSysDynamicCall(null, "_setValid", void.class, Boolean.TYPE);
}
ReturnStmtToken token = new ReturnStmtToken(new TokenMeta("", 0, 0, 0, 0));
token.setValue(null);
token.setEmpty(true);
expr.getCompiler(ReturnStmtToken.class).write(token);
}
writeFooter();
}
return entity;
}
Aggregations