softindex / datakernel

Alternative Java platform, built from the ground up - with its own async I/O core and DI. Ultra high-performance, simple and minimalistic - redefines server-side programming, web-development and highload!
https://datakernel.io
Apache License 2.0
100 stars 16 forks source link

codegen: add static fields and access to them #7

Closed Neiko2002 closed 6 years ago

Neiko2002 commented 8 years ago

Makes it possible to declare static fields ASMBuilder.staticField(...) and access their content with Expressions.getterStatic(...)/Expressions.setterStatic(...). Uses a new VarType class to define things like "io.datakernel.codegen.ExpressionTest.TestStaticField.number = 5" and introduces a static initialization block ASMBuilder.staticInitializationBlock(...).

Neiko2002 commented 8 years ago

With the new ClassScope class the AsmBuilder has now knowledge about all the parent types its depending on. This includes implemented methods and fields of a superclass and the default methods of interfaces.

lightZebra commented 8 years ago

Hello Nico. Thank you for your contibution to DataKernel.

We have reviewed your patch and here are some comments:

What do you think about that?

Neiko2002 commented 8 years ago

Hello Vlad,

I did the changes but have to say the code for static getters/setters looks quite ugly now e.g. getter(self(), "staticValue", true)

We might want to keep the getterStatic and setterStatic methods.

lightZebra commented 8 years ago

It seems that we can simplify this code by removing third argument(boolean isStatic) from getter/setter and simply check if this field is static or not:

private final Expression owner;
private final String field;

VarField(Expression owner, String field) {
    this.owner = owner;
    this.field = field;
}

@Override
public Type type(Context ctx) {
    final Type ownerType = owner.type(ctx);
    return typeOfFieldOrGetter(ctx, ownerType, field, isStatic(ctx, ownerType));
}

@Override
public Type load(Context ctx) {
    Type ownerType = isStatic(ctx, owner.type(ctx)) ? owner.type(ctx) : owner.load(ctx);
    return loadFieldOrGetter(ctx, ownerType, field, isStatic(ctx, ownerType));
}

@Override
public Object beginStore(Context ctx) {
    final Type ownerType = owner.type(ctx);
    return isStatic(ctx, ownerType) ? ownerType : owner.load(ctx);
}

@Override
public void store(Context ctx, Object storeContext, Type type) {
    final Type ownerType = owner.type(ctx);
    setField(ctx, (Type) storeContext, field, type, isStatic(ctx, ownerType));
}

private boolean isStatic(Context ctx, Type ownerType) {
    if (ctx.getThisType().equals(ownerType)) {
        return ctx.getStaticFields().containsKey(field);
    } else {
        try {
            final int modifiers = getJavaType(ctx.getClassLoader(), ownerType).getField(field).getModifiers();
            return Modifier.isPublic(modifiers) && Modifier.isStatic(modifiers);
        } catch (NoSuchFieldException e) {
            // class without public static field but with getter/setter
            return false;
        }
    }
}

Now instead of this code:

getter(self(), "value", true);
setter(self(), "value", arg(0), true);

We have this:

getter(self(), "value");
setter(self(), "value", arg(0));

If this is ok for you please update your pull request

Neiko2002 commented 8 years ago

This week is full of other things, but I will take a look at it next Monday.

Neiko2002 commented 8 years ago

Hello Vlad,

you where right. Because of the new scope class all static fields incl. derived ones, are now part of the Context.getStaticFields() result map. Allowing us to shorten the code like you mentioned.

necauqua commented 6 years ago

Static field access was added in 076af24.