package jetbrains.mps.baseLanguage.scopes; /*Generated by MPS */ import org.jetbrains.mps.openapi.model.SNode; import java.util.Map; import jetbrains.mps.lang.smodel.generator.smodelAdapter.SNodeOperations; import jetbrains.mps.smodel.adapter.structure.MetaAdapterFactory; import java.util.Set; import jetbrains.mps.internal.collections.runtime.ListSequence; import org.jetbrains.mps.openapi.language.SAbstractConcept; import jetbrains.mps.internal.collections.runtime.SetSequence; import jetbrains.mps.lang.smodel.generator.smodelAdapter.SLinkOperations; public class GenericTypesUtil { private GenericTypesUtil() { } public static SNode getTypeWithResolvedTypeVars(SNode type, Map<SNode, SNode> typeByTypeVar) { if (SNodeOperations.isInstanceOf(type, MetaAdapterFactory.getConcept(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0x102467229d8L, "jetbrains.mps.baseLanguage.structure.TypeVariableReference"))) { return GenericTypesUtil.getTypeByTypeVariable(SNodeOperations.cast(type, MetaAdapterFactory.getConcept(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0x102467229d8L, "jetbrains.mps.baseLanguage.structure.TypeVariableReference")), typeByTypeVar); } else if (SNodeOperations.isInstanceOf(type, MetaAdapterFactory.getConcept(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0x101de48bf9eL, "jetbrains.mps.baseLanguage.structure.ClassifierType"))) { return GenericTypesUtil.createClassifierTypeWithResolvedTypeVars(SNodeOperations.cast(type, MetaAdapterFactory.getConcept(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0x101de48bf9eL, "jetbrains.mps.baseLanguage.structure.ClassifierType")), typeByTypeVar); } else if (SNodeOperations.isInstanceOf(type, MetaAdapterFactory.getConcept(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0xf940d819f7L, "jetbrains.mps.baseLanguage.structure.ArrayType"))) { return GenericTypesUtil.createArrayTypeWithResolvedTypeVars(SNodeOperations.cast(type, MetaAdapterFactory.getConcept(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0xf940d819f7L, "jetbrains.mps.baseLanguage.structure.ArrayType")), typeByTypeVar); } else if (SNodeOperations.isInstanceOf(type, MetaAdapterFactory.getConcept(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0x11c08f42e7bL, "jetbrains.mps.baseLanguage.structure.VariableArityType"))) { return GenericTypesUtil.createVariableArityTypeWithResolvedTypeVars(SNodeOperations.cast(type, MetaAdapterFactory.getConcept(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0x11c08f42e7bL, "jetbrains.mps.baseLanguage.structure.VariableArityType")), typeByTypeVar); } return type; } public static SNode methodParamTypeWoutTypeVars(SNode type, Set<SNode> typeParams) { SNode typeCopy = SNodeOperations.copyNode(type); for (SNode typeVariableRef : ListSequence.fromList(SNodeOperations.getNodeDescendants(typeCopy, MetaAdapterFactory.getConcept(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0x102467229d8L, "jetbrains.mps.baseLanguage.structure.TypeVariableReference"), false, new SAbstractConcept[]{}))) { if (!(SetSequence.fromSet(typeParams).contains(SLinkOperations.getTarget(typeVariableRef, MetaAdapterFactory.getReferenceLink(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0x102467229d8L, 0x1024673a581L, "typeVariableDeclaration"))))) { // not from our type params, skipping continue; } // let's see if it's inside ? extends E or ? super E, we want to avoid invalid types like ? extends ? if (SNodeOperations.isInstanceOf(SNodeOperations.getParent(typeVariableRef), MetaAdapterFactory.getConcept(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0x110daeaa84aL, "jetbrains.mps.baseLanguage.structure.UpperBoundType")) && SNodeOperations.hasRole(typeVariableRef, MetaAdapterFactory.getContainmentLink(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0x110daeaa84aL, 0x110daeaa84bL, "bound")) || SNodeOperations.isInstanceOf(SNodeOperations.getParent(typeVariableRef), MetaAdapterFactory.getConcept(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0x110dae9d53dL, "jetbrains.mps.baseLanguage.structure.LowerBoundType")) && SNodeOperations.hasRole(typeVariableRef, MetaAdapterFactory.getContainmentLink(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0x110dae9d53dL, 0x110dae9f25bL, "bound"))) { SNodeOperations.replaceWithNewChild(SNodeOperations.getParent(typeVariableRef), MetaAdapterFactory.getConcept(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0x110dae5f4a3L, "jetbrains.mps.baseLanguage.structure.WildCardType")); } else { SNodeOperations.replaceWithNewChild(typeVariableRef, MetaAdapterFactory.getConcept(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0x110dae5f4a3L, "jetbrains.mps.baseLanguage.structure.WildCardType")); } } return typeCopy; } private static SNode getTypeByTypeVariable(SNode typeVariableRef, Map<SNode, SNode> typeByTypeVar) { SNode result = typeVariableRef; SNode typeVar = SLinkOperations.getTarget(typeVariableRef, MetaAdapterFactory.getReferenceLink(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0x102467229d8L, 0x1024673a581L, "typeVariableDeclaration")); while ((typeVar != null)) { SNode typeVarValue = typeByTypeVar.get(typeVar); if ((typeVarValue == null)) { break; } result = typeVarValue; if (SNodeOperations.isInstanceOf(result, MetaAdapterFactory.getConcept(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0x102467229d8L, "jetbrains.mps.baseLanguage.structure.TypeVariableReference"))) { SNode newTypeVar = SLinkOperations.getTarget(SNodeOperations.cast(result, MetaAdapterFactory.getConcept(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0x102467229d8L, "jetbrains.mps.baseLanguage.structure.TypeVariableReference")), MetaAdapterFactory.getReferenceLink(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0x102467229d8L, 0x1024673a581L, "typeVariableDeclaration")); if (typeVar == newTypeVar) { break; } typeVar = newTypeVar; } else { break; } } return result; } private static SNode createClassifierTypeWithResolvedTypeVars(SNode type, Map<SNode, SNode> typeByTypeVar) { if (typeByTypeVar.isEmpty()) { return type; } return SNodeOperations.cast(GenericTypesUtil.createTypeWithResolvedTypeVars(type, typeByTypeVar), MetaAdapterFactory.getConcept(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0x101de48bf9eL, "jetbrains.mps.baseLanguage.structure.ClassifierType")); } private static SNode createArrayTypeWithResolvedTypeVars(SNode type, Map<SNode, SNode> typeByTypeVar) { if (typeByTypeVar.isEmpty()) { return type; } return SNodeOperations.cast(GenericTypesUtil.createTypeWithResolvedTypeVars(type, typeByTypeVar), MetaAdapterFactory.getConcept(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0xf940d819f7L, "jetbrains.mps.baseLanguage.structure.ArrayType")); } private static SNode createVariableArityTypeWithResolvedTypeVars(SNode type, Map<SNode, SNode> typeByTypeVar) { if (typeByTypeVar.isEmpty()) { return type; } return SNodeOperations.cast(GenericTypesUtil.createTypeWithResolvedTypeVars(type, typeByTypeVar), MetaAdapterFactory.getConcept(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0x11c08f42e7bL, "jetbrains.mps.baseLanguage.structure.VariableArityType")); } private static SNode createTypeWithResolvedTypeVars(SNode type, Map<SNode, SNode> typeByTypeVar) { SNode typeCopy = SNodeOperations.copyNode(type); for (SNode typeVariableRef : ListSequence.fromList(SNodeOperations.getNodeDescendants(typeCopy, MetaAdapterFactory.getConcept(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0x102467229d8L, "jetbrains.mps.baseLanguage.structure.TypeVariableReference"), false, new SAbstractConcept[]{}))) { SNode resolvedType = GenericTypesUtil.getTypeByTypeVariable(typeVariableRef, typeByTypeVar); if (resolvedType != typeVariableRef) { SNodeOperations.replaceWithAnother(typeVariableRef, SNodeOperations.copyNode(resolvedType)); } } return typeCopy; } }