<commit_before>/*
 * Copyright LWJGL. All rights reserved.
 * License terms: http://lwjgl.org/license.php
 */
package org.lwjgl.generator

import java.io.*
import java.lang.Math.max
import java.lang.reflect.Method
import java.lang.reflect.Modifier
import java.nio.ByteBuffer
import java.util.*

/*
	A template will be generated in the following cases:

	- The target Java source does not exist.
	- The source template has a later timestamp than the target.
	- Any file in the source package has later timestamp than the target.
	- Any file in the generator itself has later timestamp than the target. (implies re-generation of all templates)

	Example template: /src/main/kotlin/org/lwjgl/opengl/templates/ARB_imaging.kt

	- Generator source      -> /src/main/kotlin/org/lwjgl/generator/
	- Source package        -> /src/main/kotlin/org/lwjgl/opengl/
	- Source template       -> /src/main/kotlin/org/lwjgl/opengl/templates/ARB_imaging.kt

	- Target source (Java)  -> modules/core/src/generated/java/org/lwjgl/opengl/ARBImaging.java
	- Target source (C)     -> modules/core/src/generated/c/opengl/org_lwjgl_opengl_ARBImaging.c
*/

enum class Binding(val key: String) {
	EGL("binding.egl"),
	GLFW("binding.glfw"),
	OPENAL("binding.openal"),
	OPENCL("binding.opencl"),
	OPENGL("binding.opengl"),
	OPENGLES("binding.opengles"),

	OVR("binding.ovr"),
	STB("binding.stb"),

	MACOSX_OBJC("binding.macosx.objc");

	val enabled: Boolean
		get() = System.getProperty(key, "false").toBoolean()
}

fun dependsOn(binding: Binding, init: () -> NativeClass): NativeClass? = if ( binding.enabled ) init() else null

fun main(args: Array<String>) {
	if ( args.size < 2 )
		throw IllegalArgumentException("The code Generator requires 2 paths as arguments: a) the template source path and b) the generation target path")

	val validateDirectory = { name: String, path: String ->
		if ( !File(path).isDirectory )
			throw IllegalArgumentException("Invalid $name path: $path")
	}

	validateDirectory("template source", args[0])
	validateDirectory("generation target", args[1])

	// Makes sure we use \n during generation, even on Windows.
	System.setProperty("line.separator", "\n")

	Generator(args[0], args[1]) {
		// We discover templates reflectively.
		// For a package passed to the generate function, we
		// search for a <package>.templates.TemplatesPackage class file
		// and run any public static methods that return a NativeClass object.

		// Note: For a Kotlin package X.Y.Z, <Z>Package is the class Kotlin generates that contains
		// all top-level functions/properties in that package. Example:
		// org.lwjgl.opengl -> org.lwjgl.opengl.OpenglPackage (the first letter is capitalized)

		generate("org.lwjgl.egl", Binding.EGL)
		generate("org.lwjgl.glfw", Binding.GLFW)
		generate("org.lwjgl.openal", Binding.OPENAL)
		generate("org.lwjgl.opencl", Binding.OPENCL)
		generate("org.lwjgl.opengl", Binding.OPENGL)
		generate("org.lwjgl.opengles", Binding.OPENGLES)
		generate("org.lwjgl.ovr", Binding.OVR)
		generate("org.lwjgl.stb", Binding.STB)

		generate("org.lwjgl.system.jemalloc")
		generate("org.lwjgl.system.libc")
		generate("org.lwjgl.system.libffi")
		generate("org.lwjgl.system.linux")
		generate("org.lwjgl.system.macosx")
		generate("org.lwjgl.system.simd")
		generate("org.lwjgl.system.windows")
		generate("org.lwjgl.system.xxhash")

		// Generate utility classes. These are auto-registered during the process above.
		generate("struct", Generator.structs)
		generate("callback", Generator.callbacks)
		generate("custom class", Generator.customClasses)

		generate(JNI)
	}
}

class Generator(
	val srcPath: String,
	val trgPath: String,
	generate: Generator.() -> Unit
) {

	companion object {
		val structs = ArrayList<Struct>()
		val callbacks = ArrayList<CallbackFunction>()
		val customClasses = ArrayList<CustomClass>()

		fun register(struct: Struct): Struct {
			structs.add(struct)
			return struct
		}

		fun register(callback: CallbackFunction) {
			callbacks.add(callback)
		}

		fun <T : CustomClass> register(customClass: T): T {
			customClasses.add(customClass)
			return customClass
		}
	}

	// TODO: add more, e.g. kotlinc
	private val GENERATOR_LAST_MODIFIED = getDirectoryLastModified("$srcPath/org/lwjgl/generator", true)

	init {
		generate()
	}

	private fun methodFilter(method: Method, javaClass: Class<*>) =
		// static
		method.modifiers and Modifier.STATIC != 0 &&
		// returns NativeClass
		method.returnType === javaClass &&
		// has no arguments
		method.parameterTypes.size == 0

	private fun apply(packagePath: String, packageName: String, consume: Sequence<Method>.() -> Unit) {
		val packageDirectory = File(packagePath)
		if ( !packageDirectory.isDirectory )
			return

		val classFiles = packageDirectory.listFiles {
			it.isFile && it.extension.equals("kt")
		}!!

		classFiles.forEach {
			try {
				Class
					.forName("$packageName.${it.nameWithoutExtension.upperCaseFirst}Kt")
					.methods
					.asSequence()
					.consume()
			} catch (e: ClassNotFoundException) {
				// ignore
			}
		}
	}

	fun generate(packageName: String, binding: Binding? = null) {
		val packagePath = "$srcPath/${packageName.replace('.', '/')}"

		val packageLastModified = getDirectoryLastModified(packagePath, false)
		packageLastModifiedMap[packageName] = packageLastModified
<commit_msg>Sort the template files by name<commit_after>/*
 * Copyright LWJGL. All rights reserved.
 * License terms: http://lwjgl.org/license.php
 */
package org.lwjgl.generator

import java.io.*
import java.lang.Math.max
import java.lang.reflect.Method
import java.lang.reflect.Modifier
import java.nio.ByteBuffer
import java.util.*

/*
	A template will be generated in the following cases:

	- The target Java source does not exist.
	- The source template has a later timestamp than the target.
	- Any file in the source package has later timestamp than the target.
	- Any file in the generator itself has later timestamp than the target. (implies re-generation of all templates)

	Example template: /src/main/kotlin/org/lwjgl/opengl/templates/ARB_imaging.kt

	- Generator source      -> /src/main/kotlin/org/lwjgl/generator/
	- Source package        -> /src/main/kotlin/org/lwjgl/opengl/
	- Source template       -> /src/main/kotlin/org/lwjgl/opengl/templates/ARB_imaging.kt

	- Target source (Java)  -> modules/core/src/generated/java/org/lwjgl/opengl/ARBImaging.java
	- Target source (C)     -> modules/core/src/generated/c/opengl/org_lwjgl_opengl_ARBImaging.c
*/

enum class Binding(val key: String) {
	EGL("binding.egl"),
	GLFW("binding.glfw"),
	OPENAL("binding.openal"),
	OPENCL("binding.opencl"),
	OPENGL("binding.opengl"),
	OPENGLES("binding.opengles"),

	OVR("binding.ovr"),
	STB("binding.stb"),

	MACOSX_OBJC("binding.macosx.objc");

	val enabled: Boolean
		get() = System.getProperty(key, "false").toBoolean()
}

fun dependsOn(binding: Binding, init: () -> NativeClass): NativeClass? = if ( binding.enabled ) init() else null

fun main(args: Array<String>) {
	if ( args.size < 2 )
		throw IllegalArgumentException("The code Generator requires 2 paths as arguments: a) the template source path and b) the generation target path")

	val validateDirectory = { name: String, path: String ->
		if ( !File(path).isDirectory )
			throw IllegalArgumentException("Invalid $name path: $path")
	}

	validateDirectory("template source", args[0])
	validateDirectory("generation target", args[1])

	// Makes sure we use \n during generation, even on Windows.
	System.setProperty("line.separator", "\n")

	Generator(args[0], args[1]) {
		// We discover templates reflectively.
		// For a package passed to the generate function, we
		// search for a <package>.templates.TemplatesPackage class file
		// and run any public static methods that return a NativeClass object.

		// Note: For a Kotlin package X.Y.Z, <Z>Package is the class Kotlin generates that contains
		// all top-level functions/properties in that package. Example:
		// org.lwjgl.opengl -> org.lwjgl.opengl.OpenglPackage (the first letter is capitalized)

		generate("org.lwjgl.egl", Binding.EGL)
		generate("org.lwjgl.glfw", Binding.GLFW)
		generate("org.lwjgl.openal", Binding.OPENAL)
		generate("org.lwjgl.opencl", Binding.OPENCL)
		generate("org.lwjgl.opengl", Binding.OPENGL)
		generate("org.lwjgl.opengles", Binding.OPENGLES)
		generate("org.lwjgl.ovr", Binding.OVR)
		generate("org.lwjgl.stb", Binding.STB)

		generate("org.lwjgl.system.jemalloc")
		generate("org.lwjgl.system.libc")
		generate("org.lwjgl.system.libffi")
		generate("org.lwjgl.system.linux")
		generate("org.lwjgl.system.macosx")
		generate("org.lwjgl.system.simd")
		generate("org.lwjgl.system.windows")
		generate("org.lwjgl.system.xxhash")

		// Generate utility classes. These are auto-registered during the process above.
		generate("struct", Generator.structs)
		generate("callback", Generator.callbacks)
		generate("custom class", Generator.customClasses)

		generate(JNI)
	}
}

class Generator(
	val srcPath: String,
	val trgPath: String,
	generate: Generator.() -> Unit
) {

	companion object {
		val structs = ArrayList<Struct>()
		val callbacks = ArrayList<CallbackFunction>()
		val customClasses = ArrayList<CustomClass>()

		fun register(struct: Struct): Struct {
			structs.add(struct)
			return struct
		}

		fun register(callback: CallbackFunction) {
			callbacks.add(callback)
		}

		fun <T : CustomClass> register(customClass: T): T {
			customClasses.add(customClass)
			return customClass
		}
	}

	// TODO: add more, e.g. kotlinc
	private val GENERATOR_LAST_MODIFIED = getDirectoryLastModified("$srcPath/org/lwjgl/generator", true)

	init {
		generate()
	}

	private fun methodFilter(method: Method, javaClass: Class<*>) =
		// static
		method.modifiers and Modifier.STATIC != 0 &&
		// returns NativeClass
		method.returnType === javaClass &&
		// has no arguments
		method.parameterTypes.size == 0

	private fun apply(packagePath: String, packageName: String, consume: Sequence<Method>.() -> Unit) {
		val packageDirectory = File(packagePath)
		if ( !packageDirectory.isDirectory )
			return

		val classFiles = packageDirectory.listFiles {
			it.isFile && it.extension.equals("kt")
		}!!

		Arrays.sort(classFiles);

		classFiles.forEach {
			try {
				Class
					.forName("$packageName.${it.nameWithoutExtension.upperCaseFirst}Kt")
					.methods
					.asSequence()
					.consume()
			} catch (e: ClassNotFoundException) {
				// ignore
			}
		}
	}

	fun generate(packageName: String, binding: Binding? = null) {
		val packagePath = "$srcPath/${packageName.replace('.', '/')}"

		val packageLastModified = getDirectoryLastModified(packagePath, false)
		packageLastModifiedMap[packageName] = packageLastModified

{'fraction_non_alphanumeric': 0.1286516853932584, 'fraction_numerical': 0.00149812734082397, 'mean_word_length': 4.142513240250361, 'pattern_counts': {'":': 0, '<': 23, '<?xml version=': 0, '>': 41, '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': '2404493', 'n_tokens_mistral': 3761, 'n_tokens_neox': 3453, 'n_words': 822}