<commit_before>package com.hexa.rebind;

import java.io.PrintWriter;
import java.util.HashMap;

import com.google.gwt.core.ext.Generator;
import com.google.gwt.core.ext.GeneratorContext;
import com.google.gwt.core.ext.TreeLogger;
import com.google.gwt.core.ext.UnableToCompleteException;
import com.google.gwt.core.ext.typeinfo.JClassType;
import com.google.gwt.core.ext.typeinfo.JGenericType;
import com.google.gwt.core.ext.typeinfo.JMethod;
import com.google.gwt.core.ext.typeinfo.JParameter;
import com.google.gwt.core.ext.typeinfo.JParameterizedType;
import com.google.gwt.core.ext.typeinfo.JType;
import com.google.gwt.core.ext.typeinfo.JTypeParameter;
import com.google.gwt.core.ext.typeinfo.TypeOracle;
import com.google.gwt.user.rebind.ClassSourceFileComposerFactory;
import com.google.gwt.user.rebind.SourceWriter;
import com.hexa.client.comm.CustomMethod;
import com.hexa.client.comm.FieldName;

public class DataProxyGenerator extends Generator
{
	private String genMethodPrototype( JMethod method )
	{
		StringBuilder sb = new StringBuilder();

		sb.append( "public " + method.getReturnType().getParameterizedQualifiedSourceName() + " " + method.getName() + "( " );

		for( int i = 0; i < method.getParameters().length; i++ )
		{
			JParameter param = method.getParameters()[i];
			sb.append( param.getType().getParameterizedQualifiedSourceName() + " " + param.getName() );
			if( i < method.getParameters().length - 1 )
				sb.append( ", " );
		}

		sb.append( " )" );

		return sb.toString();
	}

	// HexaDate fields
	HashMap<String, String> hexaDateFields = new HashMap<String, String>();

	String registerHexaDateVariable( String fieldName )
	{
		String variableName = hexaDateFields.get( fieldName );
		if( variableName == null )
		{
			variableName = "hexaDate_" + hexaDateFields.size();
			hexaDateFields.put( fieldName, variableName );
		}
		return variableName;
	}

	void generateHexaDateVariables( SourceWriter sw )
	{
		for( String variableName : hexaDateFields.values() )
			sw.println( "HexaDate " + variableName + " = null;" );
	}

	// HexaTime fields
	HashMap<String, String> hexaTimeFields = new HashMap<String, String>();

	String registerHexaTimeVariable( String fieldName )
	{
		String variableName = hexaTimeFields.get( fieldName );
		if( variableName == null )
		{
			variableName = "hexaTime_" + hexaTimeFields.size();
			hexaTimeFields.put( fieldName, variableName );
		}
		return variableName;
	}

	void generateHexaTimeVariables( SourceWriter sw )
	{
		for( String variableName : hexaTimeFields.values() )
			sw.println( "HexaTime " + variableName + " = null;" );
	}

	// HexaDateTime fields
	HashMap<String, String> hexaDateTimeFields = new HashMap<String, String>();

	String registerHexaDateTimeVariable( String fieldName )
	{
		String variableName = hexaDateTimeFields.get( fieldName );
		if( variableName == null )
		{
			variableName = "hexaDateTime_" + hexaDateTimeFields.size();
			hexaDateTimeFields.put( fieldName, variableName );
		}
		return variableName;
	}

	void generateHexaDateTimeVariables( SourceWriter sw )
	{
		for( String variableName : hexaDateTimeFields.values() )
			sw.println( "HexaDateTime " + variableName + " = null;" );
	}

	@Override
	public String generate( TreeLogger logger, GeneratorContext context, String requestedClass ) throws UnableToCompleteException
	{
		logger.log( TreeLogger.INFO, "Generate '" + requestedClass, null );

		TypeOracle typeOracle = context.getTypeOracle();

		JClassType requestedType = typeOracle.findType( requestedClass );
		if( requestedType == null )
		{
			logger.log( TreeLogger.ERROR, "Type '" + requestedClass + "' has not been found by the Oracle", null );
			throw new UnableToCompleteException();
		}

		String className = requestedType.getName() + "Impl";
		String fullClassName = requestedClass + "Impl";
		String packageName = requestedType.getPackage().getName();

		PrintWriter printWriter = context.tryCreate( logger, packageName, className );
		if( printWriter == null )
		{
			logger.log( TreeLogger.DEBUG, requestedClass + " : CANNOT CREATE PRINT WRITER", null );
			return fullClassName;
		}

		// Get type parameters informations so that we generate a fitting class
		String parameterizedTypeExt = "";
		String typeExt = "";
		JGenericType genericType = requestedType.isGenericType();
		if( genericType != null )
		{
			parameterizedTypeExt = "<";
			typeExt = "<";
			JTypeParameter[] tps = genericType.getTypeParameters();
			boolean needComa = false;
			for( int i = 0; i < tps.length; i++ )
			{
				if( needComa )
				{
					parameterizedTypeExt += ", ";
					typeExt += ", ";
				}
				needComa = true;

				JTypeParameter tp = tps[i];

				parameterizedTypeExt += tp.getName() + " extends ";
				typeExt += tp.getName();

				JClassType[] cts = tp.getBounds();
				boolean needAnd = false;
				for( int j = 0; j < cts.length; j++ )
				{
					if( needAnd )
						parameterizedTypeExt += " & ";
					needAnd = true;

					JClassType ct = cts[j];
					parameterizedTypeExt += ct.getName();
				}
			}
			parameterizedTypeExt += ">";
			typeExt += ">";
		}

		ClassSourceFileComposerFactory composerFactory = new ClassSourceFileComposerFactory( packageName, className + parameterizedTypeExt );
		composerFactory.addImport( "com.google.gwt.core.client.GWT" );
		composerFactory.addImport( "com.hexa.client.comm.DataProxy" );
		composerFactory.addImport( "com.hexa.client.comm.GenericJSO" );
		composerFactory.addImport( "com.hexa.client.comm.ResponseJSO" );
		composerFactory.addImport( "java.util.ArrayList" );
		composerFactory.addImport( "com.google.gwt.core.client.JsArray" );
		composerFactory.addImport( "com.hexa.client.common.HexaDate" );
		composerFactory.addImport( "com.hexa.client.common.HexaTime" );
		composerFactory.addImport( "com.hexa.client.common.HexaDateTime" );
		composerFactory.addImport( "com.google.gwt.core.client.JavaScriptObject" );
		composerFactory.addImplementedInterface( requestedClass + typeExt );

		SourceWriter sw = composerFactory.createSourceWriter( context, printWriter );
		if( sw == null )
		{
			// logger.log( TreeLogger.WARN, requestedClass +
			// " : CANNOT CREATE SOURCEWRITER", null );
			return fullClassName; // null, already generated
		}

		sw.println( "private GenericJSO jso = null;" );

		JMethod[] methods = requestedType.getMethods();

		sw.println( "public void init( GenericJSO jso ) {" );
		sw.indent();
		sw.println( "this.jso = jso;" );
		sw.outdent();
		sw.println( "}" );

		for( JMethod method : methods )
		{
			FieldName fnAnnotation = method.getAnnotation( FieldName.class );
			CustomMethod cmAnnotation = method.getAnnotation( CustomMethod.class );
			if( cmAnnotation != null )
			{
				sw.println( "public " + method.getReturnType().getSimpleSourceName() + " " + method.getName() + "() {" );
				sw.indent();
				sw.println( cmAnnotation.body() );
				sw.outdent();
				sw.println( "}" );<commit_msg>provide a toString() implementation for generated DataProxy classes<commit_after>package com.hexa.rebind;

import java.io.PrintWriter;
import java.util.HashMap;

import com.google.gwt.core.ext.Generator;
import com.google.gwt.core.ext.GeneratorContext;
import com.google.gwt.core.ext.TreeLogger;
import com.google.gwt.core.ext.UnableToCompleteException;
import com.google.gwt.core.ext.typeinfo.JClassType;
import com.google.gwt.core.ext.typeinfo.JGenericType;
import com.google.gwt.core.ext.typeinfo.JMethod;
import com.google.gwt.core.ext.typeinfo.JParameter;
import com.google.gwt.core.ext.typeinfo.JParameterizedType;
import com.google.gwt.core.ext.typeinfo.JType;
import com.google.gwt.core.ext.typeinfo.JTypeParameter;
import com.google.gwt.core.ext.typeinfo.TypeOracle;
import com.google.gwt.user.rebind.ClassSourceFileComposerFactory;
import com.google.gwt.user.rebind.SourceWriter;
import com.hexa.client.comm.CustomMethod;
import com.hexa.client.comm.FieldName;

public class DataProxyGenerator extends Generator
{
	private String genMethodPrototype( JMethod method )
	{
		StringBuilder sb = new StringBuilder();

		sb.append( "public " + method.getReturnType().getParameterizedQualifiedSourceName() + " " + method.getName() + "( " );

		for( int i = 0; i < method.getParameters().length; i++ )
		{
			JParameter param = method.getParameters()[i];
			sb.append( param.getType().getParameterizedQualifiedSourceName() + " " + param.getName() );
			if( i < method.getParameters().length - 1 )
				sb.append( ", " );
		}

		sb.append( " )" );

		return sb.toString();
	}

	// HexaDate fields
	HashMap<String, String> hexaDateFields = new HashMap<String, String>();

	String registerHexaDateVariable( String fieldName )
	{
		String variableName = hexaDateFields.get( fieldName );
		if( variableName == null )
		{
			variableName = "hexaDate_" + hexaDateFields.size();
			hexaDateFields.put( fieldName, variableName );
		}
		return variableName;
	}

	void generateHexaDateVariables( SourceWriter sw )
	{
		for( String variableName : hexaDateFields.values() )
			sw.println( "HexaDate " + variableName + " = null;" );
	}

	// HexaTime fields
	HashMap<String, String> hexaTimeFields = new HashMap<String, String>();

	String registerHexaTimeVariable( String fieldName )
	{
		String variableName = hexaTimeFields.get( fieldName );
		if( variableName == null )
		{
			variableName = "hexaTime_" + hexaTimeFields.size();
			hexaTimeFields.put( fieldName, variableName );
		}
		return variableName;
	}

	void generateHexaTimeVariables( SourceWriter sw )
	{
		for( String variableName : hexaTimeFields.values() )
			sw.println( "HexaTime " + variableName + " = null;" );
	}

	// HexaDateTime fields
	HashMap<String, String> hexaDateTimeFields = new HashMap<String, String>();

	String registerHexaDateTimeVariable( String fieldName )
	{
		String variableName = hexaDateTimeFields.get( fieldName );
		if( variableName == null )
		{
			variableName = "hexaDateTime_" + hexaDateTimeFields.size();
			hexaDateTimeFields.put( fieldName, variableName );
		}
		return variableName;
	}

	void generateHexaDateTimeVariables( SourceWriter sw )
	{
		for( String variableName : hexaDateTimeFields.values() )
			sw.println( "HexaDateTime " + variableName + " = null;" );
	}

	@Override
	public String generate( TreeLogger logger, GeneratorContext context, String requestedClass ) throws UnableToCompleteException
	{
		logger.log( TreeLogger.INFO, "Generate '" + requestedClass, null );

		TypeOracle typeOracle = context.getTypeOracle();

		JClassType requestedType = typeOracle.findType( requestedClass );
		if( requestedType == null )
		{
			logger.log( TreeLogger.ERROR, "Type '" + requestedClass + "' has not been found by the Oracle", null );
			throw new UnableToCompleteException();
		}

		String className = requestedType.getName() + "Impl";
		String fullClassName = requestedClass + "Impl";
		String packageName = requestedType.getPackage().getName();

		PrintWriter printWriter = context.tryCreate( logger, packageName, className );
		if( printWriter == null )
		{
			logger.log( TreeLogger.DEBUG, requestedClass + " : CANNOT CREATE PRINT WRITER", null );
			return fullClassName;
		}

		// Get type parameters informations so that we generate a fitting class
		String parameterizedTypeExt = "";
		String typeExt = "";
		JGenericType genericType = requestedType.isGenericType();
		if( genericType != null )
		{
			parameterizedTypeExt = "<";
			typeExt = "<";
			JTypeParameter[] tps = genericType.getTypeParameters();
			boolean needComa = false;
			for( int i = 0; i < tps.length; i++ )
			{
				if( needComa )
				{
					parameterizedTypeExt += ", ";
					typeExt += ", ";
				}
				needComa = true;

				JTypeParameter tp = tps[i];

				parameterizedTypeExt += tp.getName() + " extends ";
				typeExt += tp.getName();

				JClassType[] cts = tp.getBounds();
				boolean needAnd = false;
				for( int j = 0; j < cts.length; j++ )
				{
					if( needAnd )
						parameterizedTypeExt += " & ";
					needAnd = true;

					JClassType ct = cts[j];
					parameterizedTypeExt += ct.getName();
				}
			}
			parameterizedTypeExt += ">";
			typeExt += ">";
		}

		ClassSourceFileComposerFactory composerFactory = new ClassSourceFileComposerFactory( packageName, className + parameterizedTypeExt );
		composerFactory.addImport( "com.google.gwt.core.client.GWT" );
		composerFactory.addImport( "com.hexa.client.comm.DataProxy" );
		composerFactory.addImport( "com.hexa.client.comm.GenericJSO" );
		composerFactory.addImport( "com.hexa.client.comm.ResponseJSO" );
		composerFactory.addImport( "java.util.ArrayList" );
		composerFactory.addImport( "com.google.gwt.core.client.JsArray" );
		composerFactory.addImport( "com.hexa.client.common.HexaDate" );
		composerFactory.addImport( "com.hexa.client.common.HexaTime" );
		composerFactory.addImport( "com.hexa.client.common.HexaDateTime" );
		composerFactory.addImport( "com.google.gwt.core.client.JavaScriptObject" );
		composerFactory.addImport( "com.google.gwt.json.client.JSONObject" );
		composerFactory.addImplementedInterface( requestedClass + typeExt );

		SourceWriter sw = composerFactory.createSourceWriter( context, printWriter );
		if( sw == null )
		{
			// logger.log( TreeLogger.WARN, requestedClass +
			// " : CANNOT CREATE SOURCEWRITER", null );
			return fullClassName; // null, already generated
		}

		sw.println( "private GenericJSO jso = null;" );

		JMethod[] methods = requestedType.getMethods();

		sw.println( "@Override public String toString() {" );
		sw.indent();
		sw.println( "return new JSONObject(jso).toString();" );
		sw.outdent();
		sw.println( "}" );

		sw.println( "public void init( GenericJSO jso ) {" );
		sw.indent();
		sw.println( "this.jso = jso;" );
		sw.outdent();
		sw.println( "}" );

		for( JMethod method : methods )
		{
			FieldName fnAnnotation = method.getAnnotation( FieldName.class );
			CustomMethod cmAnnotation = method.getAnnotation( CustomMethod.class );
			if( cmAnnotation != null )
			{
				sw.println( "public " + method.getReturnType().getSimpleSourceName() + " " + method.getName() + "() {" );
				sw.indent();
				sw.println( cmAnnotation.body() );
				sw.outdent();
				sw.println( "}" );
{'fraction_non_alphanumeric': 0.13090083055299212, 'fraction_numerical': 0.0005678994817917229, 'mean_word_length': 4.181316660536962, 'pattern_counts': {'":': 0, '<': 27, '<?xml version=': 0, '>': 19, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7034109', 'n_tokens_mistral': 4911, 'n_tokens_neox': 4401, 'n_words': 895}