Skip to content

Commit

Permalink
Support for calling super, put, load
Browse files Browse the repository at this point in the history
- always generate a default constructor when there are none
- call super constructor
- support for put field
- support for load
  • Loading branch information
pontusmelke committed May 17, 2016
1 parent 5013957 commit edd0768
Show file tree
Hide file tree
Showing 14 changed files with 181 additions and 48 deletions.
Expand Up @@ -46,6 +46,20 @@ public static String desc( MethodDeclaration declaration )
return internalDesc( declaration.erased(), false ); return internalDesc( declaration.erased(), false );
} }


public static String desc( MethodReference reference)
{
StringBuilder builder = new StringBuilder( );
builder.append( "(" );
for ( TypeReference parameter : reference.parameters() )
{
internalType( builder, parameter, false );
}
builder.append( ")" );
internalType( builder, reference.returns(), false );

return builder.toString();
}

public static String signature( TypeReference reference ) public static String signature( TypeReference reference )
{ {
if ( !reference.isGeneric() ) if ( !reference.isGeneric() )
Expand Down
Expand Up @@ -36,6 +36,7 @@ public class ClassGenerator implements AutoCloseable
private final ClassHandle handle; private final ClassHandle handle;
private ClassEmitter emitter; private ClassEmitter emitter;
private Map<String,FieldReference> fields; private Map<String,FieldReference> fields;
private boolean hasConstructor = false;


ClassGenerator( ClassHandle handle, ClassEmitter emitter ) ClassGenerator( ClassHandle handle, ClassEmitter emitter )
{ {
Expand All @@ -46,6 +47,10 @@ public class ClassGenerator implements AutoCloseable
@Override @Override
public void close() public void close()
{ {
if (!hasConstructor)
{
generate( MethodTemplate.constructor().invokeSuper().build() );
}
emitter.done(); emitter.done();
handle.generator.closeClass(); handle.generator.closeClass();
emitter = InvalidState.CLASS_DONE; emitter = InvalidState.CLASS_DONE;
Expand Down Expand Up @@ -128,7 +133,11 @@ public CodeBlock generate( MethodDeclaration.Builder builder )


private CodeBlock generate( MethodDeclaration declaration ) private CodeBlock generate( MethodDeclaration declaration )
{ {
return new CodeBlock( this, emitter.method( declaration ) ); if (declaration.isConstructor())
{
hasConstructor = true;
}
return new CodeBlock( this, emitter.method( declaration ), declaration.parameters() );
} }


FieldReference getField( String name ) FieldReference getField( String name )
Expand Down
28 changes: 23 additions & 5 deletions community/codegen/src/main/java/org/neo4j/codegen/CodeBlock.java
Expand Up @@ -19,6 +19,9 @@
*/ */
package org.neo4j.codegen; package org.neo4j.codegen;


import java.util.HashMap;
import java.util.Map;

import static org.neo4j.codegen.Resource.withResource; import static org.neo4j.codegen.Resource.withResource;
import static org.neo4j.codegen.TypeReference.typeReference; import static org.neo4j.codegen.TypeReference.typeReference;


Expand All @@ -28,20 +31,28 @@ public class CodeBlock implements AutoCloseable
private MethodEmitter emitter; private MethodEmitter emitter;
private final CodeBlock parent; private final CodeBlock parent;
private boolean done; private boolean done;
private Map<String, LocalVariable> localVariables = new HashMap<>( );
private int varCount = 0;


CodeBlock( CodeBlock parent ) CodeBlock( CodeBlock parent )
{ {
this.clazz = parent.clazz; this.clazz = parent.clazz;
this.emitter = parent.emitter; this.emitter = parent.emitter;
parent.emitter = InvalidState.IN_SUB_BLOCK; parent.emitter = InvalidState.IN_SUB_BLOCK;
this.parent = parent; this.parent = parent;
this.localVariables = parent.localVariables;
} }


CodeBlock( ClassGenerator clazz, MethodEmitter emitter ) CodeBlock( ClassGenerator clazz, MethodEmitter emitter, Parameter...parameters )
{ {
this.clazz = clazz; this.clazz = clazz;
this.emitter = emitter; this.emitter = emitter;
this.parent = null; this.parent = null;
localVariables.put("this", localVariable( clazz.handle(), "this" ) );
for ( Parameter parameter : parameters )
{
localVariables.put( parameter.name(), localVariable( parameter.type(), parameter.name() ) );
}
} }


public ClassGenerator classGenerator() public ClassGenerator classGenerator()
Expand Down Expand Up @@ -78,14 +89,15 @@ public void expression( Expression expression )
emitter.expression( expression ); emitter.expression( expression );
} }


TypeReference local( String name ) LocalVariable local( String name )
{ {
return null; return localVariables.get( name);
} }


public LocalVariable declare( TypeReference type, String name ) public LocalVariable declare( TypeReference type, String name )
{ {
LocalVariable local = new LocalVariable( type, name ); LocalVariable local = localVariable( type, name );
localVariables.put(name, local);
emitter.declare( local ); emitter.declare( local );
return local; return local;
} }
Expand All @@ -102,6 +114,7 @@ public void assign( Class<?> type, String name, Expression value )


public void assign( TypeReference type, String name, Expression value ) public void assign( TypeReference type, String name, Expression value )
{ {
localVariables.put(name, localVariable( type, name ) );
emitter.assign( type, name, value ); emitter.assign( type, name, value );
} }


Expand All @@ -117,7 +130,7 @@ public Expression self()


public Expression load( String name ) public Expression load( String name )
{ {
return Expression.load( local( name ), name ); return Expression.load( local( name ) );
} }


public CodeBlock forEach( Parameter local, Expression iterable ) public CodeBlock forEach( Parameter local, Expression iterable )
Expand Down Expand Up @@ -187,4 +200,9 @@ public TypeReference owner()
{ {
return clazz.handle(); return clazz.handle();
} }

private LocalVariable localVariable( TypeReference type, String name )
{
return new LocalVariable( type, name, varCount++ );
}
} }
Expand Up @@ -70,14 +70,14 @@ public void accept( ExpressionVisitor visitor )
}; };
} }


static Expression load( final TypeReference type, final String name ) static Expression load( final LocalVariable variable)
{ {
return new Expression() return new Expression()
{ {
@Override @Override
public void accept( ExpressionVisitor visitor ) public void accept( ExpressionVisitor visitor )
{ {
visitor.load( type, name ); visitor.load( variable );
} }
}; };
} }
Expand Down
Expand Up @@ -19,6 +19,7 @@
*/ */
package org.neo4j.codegen; package org.neo4j.codegen;


import static org.neo4j.codegen.TypeReference.VOID;
import static org.neo4j.codegen.TypeReference.typeReference; import static org.neo4j.codegen.TypeReference.typeReference;


public abstract class ExpressionTemplate public abstract class ExpressionTemplate
Expand All @@ -30,7 +31,7 @@ public static ExpressionTemplate self()
@Override @Override
void templateAccept( CodeBlock method, ExpressionVisitor visitor ) void templateAccept( CodeBlock method, ExpressionVisitor visitor )
{ {
visitor.load( method.clazz.handle(), "this" ); visitor.load( new LocalVariable( method.clazz.handle(), "this", 0) );
} }
}; };
} }
Expand Down Expand Up @@ -85,7 +86,7 @@ public static ExpressionTemplate load( final String name )
@Override @Override
protected void templateAccept( CodeBlock method, ExpressionVisitor visitor ) protected void templateAccept( CodeBlock method, ExpressionVisitor visitor )
{ {
visitor.load( method.local( name ), name ); visitor.load( method.local( name ) );
} }
}; };
} }
Expand Down Expand Up @@ -219,16 +220,17 @@ static Expression[] materialize( CodeBlock method, ExpressionTemplate[] template
return expressions; return expressions;
} }


static ExpressionTemplate invokeSuperConstructor( final ExpressionTemplate[] parameters ) //TODO I am not crazy about the way type parameters are sent here
static ExpressionTemplate invokeSuperConstructor( final ExpressionTemplate[] parameters, final TypeReference[] parameterTypes )
{ {
// TODO: we need to get the parameter types in here eventually... assert parameters.length == parameterTypes.length;
return new ExpressionTemplate() return new ExpressionTemplate()
{ {
@Override @Override
void templateAccept( CodeBlock method, ExpressionVisitor visitor ) void templateAccept( CodeBlock method, ExpressionVisitor visitor )
{ {
visitor.invoke( Expression.SUPER, visitor.invoke( Expression.SUPER,
new MethodReference( method.clazz.handle().parent(), "<init>" ), new MethodReference( method.clazz.handle().parent(), "<init>", VOID, parameterTypes),
materialize( method, parameters ) ); materialize( method, parameters ) );
} }
}; };
Expand Down
Expand Up @@ -63,18 +63,18 @@ public void invoke( MethodReference method, Expression[] arguments )
} }


@Override @Override
public void load( TypeReference type, String name ) public void load( LocalVariable variable)
{ {
result.append( "load{type=" ); result.append( "load{type=" );
if ( type == null ) if ( variable.type() == null )
{ {
result.append( "null" ); result.append( "null" );
} }
else else
{ {
type.writeTo( result ); variable.type().writeTo( result );
} }
result.append( ", name=" ).append( name ).append( "}" ); result.append( ", name=" ).append( variable.name() ).append( "}" );
} }


@Override @Override
Expand Down
Expand Up @@ -25,7 +25,7 @@ public interface ExpressionVisitor


void invoke( MethodReference method, Expression[] arguments ); void invoke( MethodReference method, Expression[] arguments );


void load( TypeReference type, String name ); void load( LocalVariable variable);


void getField( Expression target, FieldReference field ); void getField( Expression target, FieldReference field );


Expand Down
Expand Up @@ -23,11 +23,13 @@ public class LocalVariable extends Expression
{ {
private final TypeReference type; private final TypeReference type;
private final String name; private final String name;
private final int index;


LocalVariable( TypeReference type, String name ) LocalVariable( TypeReference type, String name, int index )
{ {
this.type = type; this.type = type;
this.name = name; this.name = name;
this.index = index;
} }


public TypeReference type() public TypeReference type()
Expand All @@ -40,9 +42,14 @@ public String name()
return name; return name;
} }


public int index()
{
return index;
}

@Override @Override
public void accept( ExpressionVisitor visitor ) public void accept( ExpressionVisitor visitor )
{ {
visitor.load( type, name ); visitor.load( this );
} }
} }
Expand Up @@ -45,7 +45,7 @@ public static MethodReference methodReference( Class<?> owner, TypeReference ret
public static MethodReference methodReference( TypeReference owner, TypeReference returns, String name, public static MethodReference methodReference( TypeReference owner, TypeReference returns, String name,
TypeReference... parameters ) TypeReference... parameters )
{ {
return new MethodReference( owner, name ); return new MethodReference( owner, name, returns, parameters );
} }


public static MethodReference constructorReference( Class<?> owner, Class<?> firstParameter, Class<?>... parameters ) public static MethodReference constructorReference( Class<?> owner, Class<?> firstParameter, Class<?>... parameters )
Expand All @@ -60,17 +60,21 @@ public static MethodReference constructorReference( Class<?> owner, TypeReferenc


public static MethodReference constructorReference( TypeReference owner, TypeReference... parameters ) public static MethodReference constructorReference( TypeReference owner, TypeReference... parameters )
{ {
return new MethodReference( owner, "<init>" ); return new MethodReference( owner, "<init>", TypeReference.VOID, parameters );
} }


private final TypeReference owner; private final TypeReference owner;
private final String name; private final String name;
private final TypeReference returns;
private final TypeReference[] parameters;


MethodReference( TypeReference owner, String name ) MethodReference( TypeReference owner, String name, TypeReference returns, TypeReference[] parameters )
{ {
this.owner = owner; this.owner = owner;


this.name = name; this.name = name;
this.returns = returns;
this.parameters = parameters;
} }


public String name() public String name()
Expand All @@ -83,6 +87,16 @@ public TypeReference owner()
return owner; return owner;
} }


public TypeReference returns()
{
return returns;
}

public TypeReference[] parameters()
{
return parameters;
}

public boolean isConstructor() public boolean isConstructor()
{ {
return "<init>".equals( name ); return "<init>".equals( name );
Expand Down
Expand Up @@ -80,9 +80,26 @@ public static class ConstructorBuilder extends Builder
super( parameters ); super( parameters );
} }


public Builder invokeSuper( ExpressionTemplate... parameters ) public Builder invokeSuper()
{ {
return expression( ExpressionTemplate.invokeSuperConstructor( parameters ) ); return expression(
ExpressionTemplate.invokeSuperConstructor( new ExpressionTemplate[]{}, TypeReference.NO_TYPES ) );
}

public Builder invokeSuper( ExpressionTemplate[] parameters, Class<?>[] parameterTypes)
{
TypeReference[] references = new TypeReference[parameterTypes.length];
for ( int i = 0; i < parameterTypes.length; i++ )
{
references[i] = typeReference( parameterTypes[i] );
}

return invokeSuper( parameters, references );
}

public Builder invokeSuper( ExpressionTemplate[] parameters, TypeReference[] parameterTypes)
{
return expression( ExpressionTemplate.invokeSuperConstructor( parameters, parameterTypes ) );
} }


@Override @Override
Expand Down

0 comments on commit edd0768

Please sign in to comment.