<commit_before>package tools.vitruv.dsls.commonalities.language.elements

import java.util.HashMap
import java.util.Map
import org.eclipse.emf.common.util.URI
import org.eclipse.emf.ecore.EClass
import org.eclipse.emf.ecore.EClassifier
import org.eclipse.emf.ecore.EDataType
import org.eclipse.emf.ecore.EPackage
import org.eclipse.emf.ecore.EcorePackage
import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl
import java.util.List

class ClassifierProvider {

	val static CONTAINER_RESOURCE_URI = URI.createURI('synthetic:/commonalities/ecoreAdapters')
	public static val ClassifierProvider INSTANCE = new ClassifierProvider

	/*
	 * In order to be referenced from a Xtext language, EObjects must be
	 * contained in a resource. So we create a fake resource to put our EClass
	 * and EDataType adapters in. This resource is never serialized and has no
	 * other purpose.
	 */
	val container = new ResourceSetImpl().createResource(CONTAINER_RESOURCE_URI)
	val Map<Domain, Map<EClass, Metaclass>> metaclasses = new HashMap
	val Map<EDataType, EDataTypeClassifier> dataTypes = new HashMap

	private new() {
	}

	def dispatch Classifier toClassifier(EDataType eDataType, Domain containingDomain) {
		eDataType.toDataTypeAdapter
	}

	def dispatch Classifier toClassifier(EClass eClass, Domain containingDomain) {
		eClass.toMetaclass(containingDomain)
	}

	def toMetaclass(EClass eClass, Domain containingDomain) {
		metaclasses.computeIfAbsent(containingDomain, [new HashMap]).computeIfAbsent(eClass, [
			val adapter = LanguageElementsFactory.eINSTANCE.createEClassMetaclass
				.withClassifierProvider(this).forEClass(eClass).fromDomain(containingDomain)
			container.contents += adapter
			return adapter
		])
	}

	def toDataTypeAdapter(EDataType eDataType) {
		dataTypes.computeIfAbsent(eDataType, [
			val adapter = LanguageElementsFactory.eINSTANCE.createEDataTypeClassifier.forEDataType(eDataType)
			container.contents += adapter
			return adapter
		])
	}

	// Returns null if no corresponding EClassifier is found
	def Classifier findClassifier(Domain containingDomain, String qualifiedInstanceClassName) {
		if (qualifiedInstanceClassName.nullOrEmpty) return null
		val eClassifier = containingDomain.findEClassifier(qualifiedInstanceClassName)
		return eClassifier.toClassifier(containingDomain)
	}

	// Searches the Ecore package and the domain specific packages for a matching EClassifier:
	private static def EClassifier findEClassifier(Domain containingDomain, String qualifiedInstanceClassName) {
		if (qualifiedInstanceClassName.nullOrEmpty) return null
		var domainPackages = if (containingDomain instanceof MetamodelAdapter) {
			containingDomain.allPackages
		} else { 
			emptyList
		}
		val relevantPackages = List.of(EcorePackage.eINSTANCE) + domainPackages
		return relevantPackages.map [findEClassifier(qualifiedInstanceClassName)].filterNull.head
	}
<commit_msg>Make ClassifierProvider handle non-found classifiers<commit_after>package tools.vitruv.dsls.commonalities.language.elements

import java.util.HashMap
import java.util.Map
import org.eclipse.emf.common.util.URI
import org.eclipse.emf.ecore.EClass
import org.eclipse.emf.ecore.EClassifier
import org.eclipse.emf.ecore.EDataType
import org.eclipse.emf.ecore.EPackage
import org.eclipse.emf.ecore.EcorePackage
import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl
import java.util.List

class ClassifierProvider {

	val static CONTAINER_RESOURCE_URI = URI.createURI('synthetic:/commonalities/ecoreAdapters')
	public static val ClassifierProvider INSTANCE = new ClassifierProvider

	/*
	 * In order to be referenced from a Xtext language, EObjects must be
	 * contained in a resource. So we create a fake resource to put our EClass
	 * and EDataType adapters in. This resource is never serialized and has no
	 * other purpose.
	 */
	val container = new ResourceSetImpl().createResource(CONTAINER_RESOURCE_URI)
	val Map<Domain, Map<EClass, Metaclass>> metaclasses = new HashMap
	val Map<EDataType, EDataTypeClassifier> dataTypes = new HashMap

	private new() {
	}

	def dispatch Classifier toClassifier(EDataType eDataType, Domain containingDomain) {
		eDataType.toDataTypeAdapter
	}

	def dispatch Classifier toClassifier(EClass eClass, Domain containingDomain) {
		eClass.toMetaclass(containingDomain)
	}

	def toMetaclass(EClass eClass, Domain containingDomain) {
		metaclasses.computeIfAbsent(containingDomain, [new HashMap]).computeIfAbsent(eClass, [
			val adapter = LanguageElementsFactory.eINSTANCE.createEClassMetaclass
				.withClassifierProvider(this).forEClass(eClass).fromDomain(containingDomain)
			container.contents += adapter
			return adapter
		])
	}

	def toDataTypeAdapter(EDataType eDataType) {
		dataTypes.computeIfAbsent(eDataType, [
			val adapter = LanguageElementsFactory.eINSTANCE.createEDataTypeClassifier.forEDataType(eDataType)
			container.contents += adapter
			return adapter
		])
	}

	// Returns null if no corresponding EClassifier is found
	def Classifier findClassifier(Domain containingDomain, String qualifiedInstanceClassName) {
		if (qualifiedInstanceClassName.nullOrEmpty) return null
		val eClassifier = containingDomain.findEClassifier(qualifiedInstanceClassName)
		return eClassifier?.toClassifier(containingDomain)
	}

	// Searches the Ecore package and the domain specific packages for a matching EClassifier:
	private static def EClassifier findEClassifier(Domain containingDomain, String qualifiedInstanceClassName) {
		if (qualifiedInstanceClassName.nullOrEmpty) return null
		var domainPackages = if (containingDomain instanceof MetamodelAdapter) {
			containingDomain.allPackages
		} else { 
			emptyList
		}
		val relevantPackages = List.of(EcorePackage.eINSTANCE) + domainPackages
		return relevantPackages.map [findEClassifier(qualifiedInstanceClassName)].filterNull.head
	}

{'fraction_non_alphanumeric': 0.07012719147473359, 'fraction_numerical': 0.0, 'mean_word_length': 5.7662790697674415, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 9, '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': '3322741', 'n_tokens_mistral': 1768, 'n_tokens_neox': 1650, 'n_words': 406}