<commit_before>package fr.inria.diverse.k3.sle.typing

import fr.inria.diverse.k3.sle.ast.ASTProcessingException

import fr.inria.diverse.k3.sle.lib.ModelUtils

import fr.inria.diverse.k3.sle.metamodel.k3sle.K3sleFactory
import fr.inria.diverse.k3.sle.metamodel.k3sle.ModelTypingSpace
import fr.inria.diverse.k3.sle.metamodel.k3sle.Transformation
import fr.inria.diverse.k3.sle.metamodel.k3sle.ModelType
import fr.inria.diverse.k3.sle.metamodel.k3sle.Metamodel
import fr.inria.diverse.k3.sle.metamodel.k3sle.ResourceType

import org.eclipse.emf.ecore.util.EcoreUtil
import org.eclipse.emf.ecore.EcoreFactory
import org.eclipse.emf.ecore.EClass

import org.eclipse.xtext.common.types.JvmDeclaredType

import static extension fr.inria.diverse.k3.sle.ast.ASTHelper.*
import static extension fr.inria.diverse.k3.sle.ast.MetamodelExtensions.*
import static extension fr.inria.diverse.k3.sle.ast.ModelTypeExtensions.*

import static extension fr.inria.diverse.k3.sle.lib.EcoreExtensions.*

class K3SLETyping
{
	def inferTypingRelations(ModelTypingSpace root) {
		root.modelTypes
		.forEach[mt1 |
			root.modelTypes
			.filter[mt2 | mt2 != mt1 && !mt1.subtypingRelations.exists[superType?.name == mt2?.name] && mt1.subtypeOf(mt2)]
			.forEach[mt2 |
				mt1.subtypingRelations += K3sleFactory.eINSTANCE.createSubtyping => [
					subType = mt1
					superType = mt2
				]
			]

			root.metamodels
			.filter[mm | !mm.^implements.exists[name == mt1.name] && mm.typedBy(mt1)]
			.forEach[mm |
				mm.^implements += mt1
			]
		]
	}

	def dispatch void complete(ModelTypingSpace root) {
		val newMTs = newArrayList

		root.metamodels.forEach[mm |
			val newMT = K3sleFactory.eINSTANCE.createModelType => [
				name = mm.exactTypeRef
			]

			if (!root.modelTypes.exists[name == newMT.name])
				newMTs += newMT
		]

		root.elements += newMTs
		root.metamodels.forEach[mm |
			mm.exactType = root.modelTypes.findFirst[name == mm.exactTypeRef]
		]

		root.elements.forEach[complete]
	}

	def dispatch void complete(Metamodel mm) {
		if (mm.hasSuperMetamodel) {
			// EMF resource = extension with inheritance
			if (mm.resourceType == ResourceType.EMF) {
				val pkg = ModelUtils.loadPkg(mm.inheritanceRelation.superMetamodel.ecore.uri)

				val newPkg = EcoreFactory.eINSTANCE.createEPackage => [
					name = mm.name.toLowerCase
					nsURI = mm.resourceUri ?: '''http://«mm.name.toLowerCase»'''
					nsPrefix = mm.name.toLowerCase

					pkg.EClassifiers.filter(EClass).forEach[cls |
						EClassifiers += EcoreFactory.eINSTANCE.createEClass => [newCls |
							newCls.name = cls.name
							newCls.ESuperTypes += cls
						]
					]
				]

				if (!mm.pkgs.exists[nsURI == newPkg.nsURI])
					mm.pkgs += newPkg

				mm.aspects.forEach[asp |
					if (!(asp.aspectRef.type instanceof JvmDeclaredType))
						throw new ASTProcessingException("Aspect must be a generic type: " + asp.aspectRef?.type)

					val className = asp.aspectAnnotationValue

					if (className === null)
						throw new ASTProcessingException("Cannot find annotation value for " + asp.aspectRef?.type)

					val cls = mm.findClass(className)

					if (cls === null)
						throw new ASTProcessingException("Cannot find aspectized class for " + asp.aspectRef?.type)

					asp.aspectedClass = cls

					mm.weaveAspect(asp.aspectedClass, asp.aspectRef.type as JvmDeclaredType)
				]

				val copy = EcoreUtil.copy(newPkg)
				val ecoreUri = '''platform:/resource/«mm.project.name»/model/«mm.name».ecore'''
				val genmodelUri = '''platform:/resource/«mm.project.name»/model/«mm.name».genmodel'''
				val srcFolder = '''«mm.project.name»/src'''
				copy.createEcore(ecoreUri)
				copy.createGenModel(mm, ecoreUri, genmodelUri, srcFolder)

				throw new ASTProcessingException("Gemoc: stop here")
			} else {
				val rootPkg = mm.inheritanceRelation.superMetamodel.pkgs.head.copy(mm.name)

				val pkg = rootPkg
				if (!mm.pkgs.exists[nsURI == pkg.nsURI])
					mm.pkgs += pkg

				pkg.referencedPkgs.filterNull.forEach[p |
					if (!mm.pkgs.exists[nsURI == p.nsURI])
						mm.pkgs += p
				]

				mm.aspects.forEach[asp |<commit_msg>k3-sle: Fix generation problem in Gemoc<commit_after>package fr.inria.diverse.k3.sle.typing

import fr.inria.diverse.k3.sle.ast.ASTProcessingException

import fr.inria.diverse.k3.sle.lib.ModelUtils

import fr.inria.diverse.k3.sle.metamodel.k3sle.K3sleFactory
import fr.inria.diverse.k3.sle.metamodel.k3sle.ModelTypingSpace
import fr.inria.diverse.k3.sle.metamodel.k3sle.Transformation
import fr.inria.diverse.k3.sle.metamodel.k3sle.ModelType
import fr.inria.diverse.k3.sle.metamodel.k3sle.Metamodel
import fr.inria.diverse.k3.sle.metamodel.k3sle.ResourceType

import org.eclipse.emf.ecore.util.EcoreUtil
import org.eclipse.emf.ecore.EcoreFactory
import org.eclipse.emf.ecore.EClass

import org.eclipse.xtext.common.types.JvmDeclaredType

import static extension fr.inria.diverse.k3.sle.ast.ASTHelper.*
import static extension fr.inria.diverse.k3.sle.ast.MetamodelExtensions.*
import static extension fr.inria.diverse.k3.sle.ast.ModelTypeExtensions.*

import static extension fr.inria.diverse.k3.sle.lib.EcoreExtensions.*

class K3SLETyping
{
	def inferTypingRelations(ModelTypingSpace root) {
		root.modelTypes
		.forEach[mt1 |
			root.modelTypes
			.filter[mt2 | mt2 != mt1 && !mt1.subtypingRelations.exists[superType?.name == mt2?.name] && mt1.subtypeOf(mt2)]
			.forEach[mt2 |
				mt1.subtypingRelations += K3sleFactory.eINSTANCE.createSubtyping => [
					subType = mt1
					superType = mt2
				]
			]

			root.metamodels
			.filter[mm | !mm.^implements.exists[name == mt1.name] && mm.typedBy(mt1)]
			.forEach[mm |
				mm.^implements += mt1
			]
		]
	}

	def dispatch void complete(ModelTypingSpace root) {
		val newMTs = newArrayList

		root.metamodels.forEach[mm |
			val newMT = K3sleFactory.eINSTANCE.createModelType => [
				name = mm.exactTypeRef
			]

			if (!root.modelTypes.exists[name == newMT.name])
				newMTs += newMT
		]

		root.elements += newMTs
		root.metamodels.forEach[mm |
			mm.exactType = root.modelTypes.findFirst[name == mm.exactTypeRef]
		]

		root.elements.forEach[complete]
	}

	def dispatch void complete(Metamodel mm) {
		if (mm.hasSuperMetamodel) {
			// EMF resource = extension with inheritance
			if (mm.resourceType == ResourceType.EMF) {
				val pkg = ModelUtils.loadPkg(mm.inheritanceRelation.superMetamodel.ecore.uri)

				val newPkg = EcoreFactory.eINSTANCE.createEPackage => [
					name = mm.name.toLowerCase
					nsURI = mm.resourceUri ?: '''http://«mm.name.toLowerCase»'''
					nsPrefix = mm.name.toLowerCase

					pkg.EClassifiers.filter(EClass).forEach[cls |
						EClassifiers += EcoreFactory.eINSTANCE.createEClass => [newCls |
							newCls.name = cls.name
							newCls.ESuperTypes += cls
						]
					]
				]

				if (!mm.pkgs.exists[nsURI == newPkg.nsURI])
					mm.pkgs += newPkg

				mm.aspects.forEach[asp |
					if (!(asp.aspectRef.type instanceof JvmDeclaredType))
						throw new ASTProcessingException("Aspect must be a generic type: " + asp.aspectRef?.type)

					val className = asp.aspectAnnotationValue

					if (className === null)
						throw new ASTProcessingException("Cannot find annotation value for " + asp.aspectRef?.type)

					val cls = mm.findClass(className)

					if (cls === null)
						throw new ASTProcessingException("Cannot find aspectized class for " + asp.aspectRef?.type)

					asp.aspectedClass = cls

					mm.weaveAspect(asp.aspectedClass, asp.aspectRef.type as JvmDeclaredType)
				]

				val copy = EcoreUtil.copy(mm.pkgs.head)
				val ecoreUri = '''platform:/resource/«mm.project.name»/model/«mm.name».ecore'''
				val genmodelUri = '''platform:/resource/«mm.project.name»/model/«mm.name».genmodel'''
				val srcFolder = '''«mm.project.name»/src'''
				copy.createEcore(ecoreUri)
				copy.createGenModel(mm, ecoreUri, genmodelUri, srcFolder)

				throw new ASTProcessingException("Gemoc: stop here")
			} else {
				val rootPkg = mm.inheritanceRelation.superMetamodel.pkgs.head.copy(mm.name)

				val pkg = rootPkg
				if (!mm.pkgs.exists[nsURI == pkg.nsURI])
					mm.pkgs += pkg

				pkg.referencedPkgs.filterNull.forEach[p |
					if (!mm.pkgs.exists[nsURI == p.nsURI])
						mm.pkgs += p
				]

				mm.aspects.forEach[asp |
{'fraction_non_alphanumeric': 0.12542703757930698, 'fraction_numerical': 0.009394826744753539, 'mean_word_length': 3.597307908020191, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 11, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 1, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '834373', 'n_tokens_mistral': 3495, 'n_tokens_neox': 2972, 'n_words': 503}