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 );
}

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

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

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 )
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;

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

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

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

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

CodeBlock( ClassGenerator clazz, MethodEmitter emitter )
CodeBlock( ClassGenerator clazz, MethodEmitter emitter, Parameter...parameters )
{
this.clazz = clazz;
this.emitter = emitter;
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()
Expand Down Expand Up @@ -78,14 +89,15 @@ public void expression( 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 )
{
LocalVariable local = new LocalVariable( type, name );
LocalVariable local = localVariable( type, name );
localVariables.put(name, local);
emitter.declare( 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 )
{
localVariables.put(name, localVariable( type, name ) );
emitter.assign( type, name, value );
}

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

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

public CodeBlock forEach( Parameter local, Expression iterable )
Expand Down Expand Up @@ -187,4 +200,9 @@ public TypeReference owner()
{
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()
{
@Override
public void accept( ExpressionVisitor visitor )
{
visitor.load( type, name );
visitor.load( variable );
}
};
}
Expand Down
Expand Up @@ -19,6 +19,7 @@
*/
package org.neo4j.codegen;

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

public abstract class ExpressionTemplate
Expand All @@ -30,7 +31,7 @@ public static ExpressionTemplate self()
@Override
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
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;
}

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()
{
@Override
void templateAccept( CodeBlock method, ExpressionVisitor visitor )
{
visitor.invoke( Expression.SUPER,
new MethodReference( method.clazz.handle().parent(), "<init>" ),
new MethodReference( method.clazz.handle().parent(), "<init>", VOID, parameterTypes),
materialize( method, parameters ) );
}
};
Expand Down
Expand Up @@ -63,18 +63,18 @@ public void invoke( MethodReference method, Expression[] arguments )
}

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

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

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

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

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 String name;
private final int index;

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

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

public int index()
{
return index;
}

@Override
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,
TypeReference... parameters )
{
return new MethodReference( owner, name );
return new MethodReference( owner, name, returns, 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 )
{
return new MethodReference( owner, "<init>" );
return new MethodReference( owner, "<init>", TypeReference.VOID, parameters );
}

private final TypeReference owner;
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.name = name;
this.returns = returns;
this.parameters = parameters;
}

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

public TypeReference returns()
{
return returns;
}

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

public boolean isConstructor()
{
return "<init>".equals( name );
Expand Down
Expand Up @@ -80,9 +80,26 @@ public static class ConstructorBuilder extends Builder
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
Expand Down

0 comments on commit edd0768

Please sign in to comment.