Changeset 13422


Ignore:
Timestamp:
11/30/15 15:12:34 (4 years ago)
Author:
mkommend
Message:

#2521: Adapted type discovery and type selector to allow the creation of generic programmable problems.

Location:
branches/ProblemRefactoring
Files:
8 edited

Legend:

Unmodified
Added
Removed
  • branches/ProblemRefactoring/HeuristicLab.Core.Views/3.3/TypeSelector.cs

    r12722 r13422  
    257257    }
    258258
     259    private Type[] genericTypeArguments = null;
    259260    protected virtual void UpdateTypeParameters() {
    260261      typeParametersListView.Items.Clear();
     
    262263        typeParametersGroupBox.Enabled = false;
    263264        typeParametersSplitContainer.Panel2Collapsed = true;
     265        genericTypeArguments = null;
    264266      } else {
    265267        typeParametersGroupBox.Enabled = true;
     
    267269        setTypeParameterButton.Enabled = false;
    268270
    269         foreach (Type param in SelectedType.GetGenericArguments()) {
     271
     272        genericTypeArguments = SelectedType.GetGenericArguments();
     273
     274        foreach (Type param in genericTypeArguments) {
    270275          if (param.IsGenericParameter) {
    271276            ListViewItem item = new ListViewItem();
     
    301306      if (typeSelectorDialog.ShowDialog(this) == DialogResult.OK) {
    302307        Type selected = typeSelectorDialog.TypeSelector.SelectedType;
    303         Type[] parameters = SelectedType.GetGenericArguments();
    304         parameters[param.GenericParameterPosition] = selected;
    305         SelectedType = SelectedType.GetGenericTypeDefinition().MakeGenericType(parameters);
     308        genericTypeArguments[param.GenericParameterPosition] = selected;
     309        if (genericTypeArguments.All(p => !p.IsGenericParameter))
     310          SelectedType = SelectedType.GetGenericTypeDefinition().MakeGenericType(genericTypeArguments);
    306311
    307312        typeParametersListView.SelectedItems[0].Text = param.Name + ": " + selected.GetPrettyName();
  • branches/ProblemRefactoring/HeuristicLab.Core.Views/3.3/TypeSelectorDialog.cs

    r12012 r13422  
    5858    }
    5959    protected virtual void typeSelector_SelectedTypeChanged(object sender, EventArgs e) {
    60       okButton.Enabled = typeSelector.SelectedType != null;
     60      var selectedType = typeSelector.SelectedType;
     61      okButton.Enabled = selectedType != null && !selectedType.IsGenericTypeDefinition;
    6162    }
    6263    protected virtual void TypesTreeView_DoubleClick(object sender, System.EventArgs e) {
  • branches/ProblemRefactoring/HeuristicLab.PluginInfrastructure/3.3/LightweightApplicationManager.cs

    r12012 r13422  
    131131                            let t = assemblyType.BuildType(type)
    132132                            where t != null
    133                             where t.IsSubTypeOf(type)
     133                            where t.IsAssignableTo(type)
    134134                            where !t.IsNonDiscoverableType()
    135135                            where onlyInstantiable == false || (!t.IsAbstract && !t.IsInterface && !t.HasElementType)
  • branches/ProblemRefactoring/HeuristicLab.PluginInfrastructure/3.3/SandboxApplicationManager.cs

    r12012 r13422  
    264264                          let t = assemblyType.BuildType(type)
    265265                          where t != null
    266                           where t.IsSubTypeOf(type)
     266                          where t.IsAssignableTo(type)
    267267                          where !t.IsNonDiscoverableType()
    268268                          where onlyInstantiable == false || (!t.IsAbstract && !t.IsInterface && !t.HasElementType)
  • branches/ProblemRefactoring/HeuristicLab.PluginInfrastructure/3.3/TypeExtensions.cs

    r12012 r13422  
    7676    }
    7777
    78     internal static bool IsSubTypeOf(this Type subType, Type baseType) {
     78    internal static bool IsAssignableTo(this Type subType, Type baseType) {
    7979      if (baseType.IsAssignableFrom(subType)) return true;
     80
     81      //check generics
    8082      if (!baseType.IsGenericType) return false;
     83      if (RecursiveCheckGenericTypes(baseType, subType)) return true;
    8184
    82       if (RecursiveCheckGenericTypes(baseType, subType)) return true;
     85      //check generic interfaces
    8386      IEnumerable<Type> implementedInterfaces = subType.GetInterfaces().Where(t => t.IsGenericType);
    84       foreach (var implementedInterface in implementedInterfaces.Where(i => i.IsGenericType)) {
    85         if (baseType.CheckGenericTypes(implementedInterface)) return true;
    86       }
    87 
    88       return false;
     87      return implementedInterfaces.Any(implementedInterface => baseType.CheckGenericTypes(implementedInterface));
    8988    }
    9089
    9190    private static bool RecursiveCheckGenericTypes(Type baseType, Type subType) {
    9291      if (!baseType.IsGenericType) return false;
    93       if (!subType.IsGenericType) return false;
    94       if (baseType.CheckGenericTypes(subType)) return true;
     92      if (subType.IsGenericType && baseType.CheckGenericTypes(subType)) return true;
    9593      if (subType.BaseType == null) return false;
    9694
     
    102100      var subTypeGenericTypeDefinition = subType.GetGenericTypeDefinition();
    103101      if (baseTypeGenericTypeDefinition != subTypeGenericTypeDefinition) return false;
     102
    104103      var baseTypeGenericArguments = baseType.GetGenericArguments();
    105104      var subTypeGenericArguments = subType.GetGenericArguments();
     
    109108        var subTypeGenericArgument = subTypeGenericArguments[i];
    110109
    111         if (baseTypeGenericArgument.IsGenericParameter ^ subTypeGenericArgument.IsGenericParameter) return false;
    112         if (baseTypeGenericArgument == subTypeGenericArgument) continue;
    113         if (!baseTypeGenericArgument.IsGenericParameter && !subTypeGenericArgument.IsGenericParameter) return false;
     110        //no generic parameters => concrete types => check for type equality (ignore co- and contravariance)
     111        //for example List<int> is only a List<int>, IParameter<IItem> is not a base type of IParameter<DoubleValue>
     112        if (!baseTypeGenericArgument.IsGenericParameter && !subTypeGenericArgument.IsGenericParameter) {
     113          if (baseTypeGenericArgument == subTypeGenericArgument) continue;
     114          return false;
     115        }
    114116
    115         if (baseTypeGenericArgument.GenericParameterAttributes.HasFlag(GenericParameterAttributes.ReferenceTypeConstraint) &&
    116             !subTypeGenericArgument.GenericParameterAttributes.HasFlag(GenericParameterAttributes.ReferenceTypeConstraint)) return false;
    117         if (baseTypeGenericArgument.GenericParameterAttributes.HasFlag(GenericParameterAttributes.DefaultConstructorConstraint) &&
    118             !subTypeGenericArgument.GenericParameterAttributes.HasFlag(GenericParameterAttributes.DefaultConstructorConstraint)) return false;
    119         if (baseTypeGenericArgument.GenericParameterAttributes.HasFlag(GenericParameterAttributes.NotNullableValueTypeConstraint) &&
    120             !subTypeGenericArgument.GenericParameterAttributes.HasFlag(GenericParameterAttributes.NotNullableValueTypeConstraint)) return false;
     117        //baseTypeGenericArgument is a concrete type and the subTypeGenericArgument is a generic parameter
     118        //for example List<int> is not a base type of List<T>
     119        if (!baseTypeGenericArgument.IsGenericParameter && subTypeGenericArgument.IsGenericParameter) return false;
    121120
    122         foreach (var baseTypeGenericParameterConstraint in baseTypeGenericArgument.GetGenericParameterConstraints()) {
    123           if (!subTypeGenericArgument.GetGenericParameterConstraints().Any(t => baseTypeGenericParameterConstraint.IsAssignableFrom(t))) return false;
     121        //baseTypeGenericArugment is a generic parameter and the subTypeGenericArgument is a concrete type => check type constraints
     122        //for example IParameter<T> is a base type of IParameter<IItem> if all generic contraints on T are fulfilled
     123        if (baseTypeGenericArgument.IsGenericParameter && !subTypeGenericArgument.IsGenericParameter) {
     124          if (baseTypeGenericArgument.GenericParameterAttributes.HasFlag(GenericParameterAttributes.ReferenceTypeConstraint) &&
     125            subTypeGenericArgument.IsValueType) return false;
     126          if (baseTypeGenericArgument.GenericParameterAttributes.HasFlag(GenericParameterAttributes.DefaultConstructorConstraint) &&
     127            subTypeGenericArgument.GetConstructor(Type.EmptyTypes) == null) return false;
     128          if (baseTypeGenericArgument.GenericParameterAttributes.HasFlag(GenericParameterAttributes.NotNullableValueTypeConstraint)) {
     129            if (!subTypeGenericArgument.IsValueType) return false;
     130            if (subTypeGenericArgument.IsGenericType && subTypeGenericArgument.GetGenericTypeDefinition() == typeof(Nullable<>))
     131              return false;
     132          }
     133
     134          //not assignable if the subTypeGenericArgument is not assignable to all of the constraints of the base type
     135          if (baseTypeGenericArgument.GetGenericParameterConstraints().Any(baseTypeGenericParameterConstraint =>
     136            !baseTypeGenericParameterConstraint.IsAssignableFrom(subTypeGenericArgument)))
     137            return false;
     138        }
     139
     140        //both generic arguments are generic parameters => check type constraints
     141        //for example IParameter<T> is a base type of IParameter<T>
     142        if (baseTypeGenericArgument.IsGenericParameter && subTypeGenericArgument.IsGenericParameter) {
     143          if (baseTypeGenericArgument.GenericParameterAttributes.HasFlag(GenericParameterAttributes.ReferenceTypeConstraint) &&
     144              !subTypeGenericArgument.GenericParameterAttributes.HasFlag(GenericParameterAttributes.ReferenceTypeConstraint)) return false;
     145          if (baseTypeGenericArgument.GenericParameterAttributes.HasFlag(GenericParameterAttributes.DefaultConstructorConstraint) &&
     146              !subTypeGenericArgument.GenericParameterAttributes.HasFlag(GenericParameterAttributes.DefaultConstructorConstraint)) return false;
     147          if (baseTypeGenericArgument.GenericParameterAttributes.HasFlag(GenericParameterAttributes.NotNullableValueTypeConstraint) &&
     148              !subTypeGenericArgument.GenericParameterAttributes.HasFlag(GenericParameterAttributes.NotNullableValueTypeConstraint)) return false;
     149
     150          //not assignable if any of the constraints is not assignable to the constraints of the base type
     151          if (baseTypeGenericArgument.GetGenericParameterConstraints().Any(baseTypeGenericParameterConstraint => !subTypeGenericArgument.GetGenericParameterConstraints().Any(t => baseTypeGenericParameterConstraint.IsAssignableFrom(t)))) {
     152            return false;
     153          }
    124154        }
    125155      }
  • branches/ProblemRefactoring/HeuristicLab.Problems.Programmable/3.3/MultiObjectiveProgrammableProblem.cs

    r13390 r13422  
    3434  [Creatable(CreatableAttribute.Categories.Problems, Priority = 120)]
    3535  [StorableClass]
    36   public abstract class MultiObjectiveProgrammableProblem<TEncoding, TSolution> : MultiObjectiveProblem<TEncoding, TSolution>, IProgrammableItem, IProgrammableProblem
     36  public class MultiObjectiveProgrammableProblem<TEncoding, TSolution> : MultiObjectiveProblem<TEncoding, TSolution>, IProgrammableItem, IProgrammableProblem
    3737    where TEncoding : class, IEncoding<TSolution>
    3838    where TSolution : class, ISolution {
     
    6666      RegisterEvents();
    6767    }
     68
     69    public override IDeepCloneable Clone(Cloner cloner) {
     70      return new MultiObjectiveProgrammableProblem<TEncoding, TSolution>(this, cloner);
     71    }
     72
    6873    public MultiObjectiveProgrammableProblem()
    6974      : base() {
     
    7176        new MultiObjectiveProblemDefinitionScript<TEncoding, TSolution>() { Name = Name }));
    7277      ProblemScript.Encoding = (TEncoding)Encoding.Clone();
     78
     79      var codeTemplate = ScriptTemplates.MultiObjectiveProblem_Template;
     80      codeTemplate = codeTemplate.Replace(ENCODING_NAMESPACE, typeof(TEncoding).Namespace);
     81      codeTemplate = codeTemplate.Replace(ENCODING_CLASS, typeof(TEncoding).Name);
     82      codeTemplate = codeTemplate.Replace(SOLUTION_CLASS, typeof(TSolution).Name);
     83      ProblemScript.Code = codeTemplate;
     84
    7385      RegisterEvents();
    7486    }
  • branches/ProblemRefactoring/HeuristicLab.Problems.Programmable/3.3/SingleObjectiveProgrammableProblem.cs

    r13390 r13422  
    3434namespace HeuristicLab.Problems.Programmable {
    3535  [Item("Programmable Problem (single-objective)", "Represents a single-objective problem that can be programmed with a script.")]
     36  [Creatable(CreatableAttribute.Categories.Problems, Priority = 110)]
    3637  [StorableClass]
    37   public abstract class SingleObjectiveProgrammableProblem<TEncoding, TSolution> : SingleObjectiveProblem<TEncoding, TSolution>, IProgrammableItem, IProgrammableProblem
     38  public class SingleObjectiveProgrammableProblem<TEncoding, TSolution> : SingleObjectiveProblem<TEncoding, TSolution>, IProgrammableItem, IProgrammableProblem
    3839    where TEncoding : class, IEncoding<TSolution>
    3940    where TSolution : class, ISolution {
     
    6768      RegisterEvents();
    6869    }
     70
     71    public override IDeepCloneable Clone(Cloner cloner) {
     72      return new SingleObjectiveProgrammableProblem<TEncoding, TSolution>(this, cloner);
     73    }
     74
    6975    public SingleObjectiveProgrammableProblem()
    7076      : base() {
    71       Parameters.Add(new FixedValueParameter<SingleObjectiveProblemDefinitionScript<TEncoding, TSolution>>("ProblemScript", "Defines the problem.",
    72         new SingleObjectiveProblemDefinitionScript<TEncoding, TSolution>() { Name = Name }));
     77      Parameters.Add(new FixedValueParameter<SingleObjectiveProblemDefinitionScript<TEncoding, TSolution>>("ProblemScript", "Defines the problem.", new SingleObjectiveProblemDefinitionScript<TEncoding, TSolution>() { Name = Name }));
    7378      ProblemScript.Encoding = (TEncoding)Encoding.Clone();
     79
     80      var codeTemplate = ScriptTemplates.SingleObjectiveProblem_Template;
     81      codeTemplate = codeTemplate.Replace(ENCODING_NAMESPACE, typeof(TEncoding).Namespace);
     82      codeTemplate = codeTemplate.Replace(ENCODING_CLASS, typeof(TEncoding).Name);
     83      codeTemplate = codeTemplate.Replace(SOLUTION_CLASS, typeof(TSolution).Name);
     84      ProblemScript.Code = codeTemplate;
     85
    7486      Operators.Add(new BestScopeSolutionAnalyzer());
    7587      RegisterEvents();
  • branches/ProblemRefactoring/HeuristicLab.Tests/HeuristicLab.PluginInfraStructure-3.3/TypeExtensionsTest.cs

    r12012 r13422  
    3636    [TestProperty("Time", "short")]
    3737    public void IsSubTypeOfTest() {
    38       Assert.IsTrue(typeof(int).IsSubTypeOf(typeof(object)));
    39       Assert.IsTrue(typeof(IntValue).IsSubTypeOf(typeof(IItem)));
    40       Assert.IsTrue(typeof(List<int>).IsSubTypeOf(typeof(object)));
     38      Assert.IsTrue(typeof(int).IsAssignableTo(typeof(object)));
     39      Assert.IsTrue(typeof(IntValue).IsAssignableTo(typeof(IItem)));
     40      Assert.IsTrue(typeof(List<int>).IsAssignableTo(typeof(object)));
    4141
    42       Assert.IsTrue(typeof(List<int>).IsSubTypeOf(typeof(IList)));
    43       Assert.IsTrue(typeof(List<>).IsSubTypeOf(typeof(IList)));
    44       Assert.IsFalse(typeof(NamedItemCollection<>).IsSubTypeOf(typeof(ICollection<IItem>)));
    45       Assert.IsFalse(typeof(NamedItemCollection<>).IsSubTypeOf(typeof(ICollection<NamedItem>)));
     42      Assert.IsTrue(typeof(List<int>).IsAssignableTo(typeof(IList)));
     43      Assert.IsTrue(typeof(List<>).IsAssignableTo(typeof(IList)));
     44      Assert.IsFalse(typeof(NamedItemCollection<>).IsAssignableTo(typeof(ICollection<IItem>)));
     45      Assert.IsFalse(typeof(NamedItemCollection<>).IsAssignableTo(typeof(ICollection<NamedItem>)));
     46
     47      //new tests     
    4648
    4749
    48       Assert.IsTrue(typeof(List<IItem>).IsSubTypeOf(typeof(IList<IItem>)));
    49       Assert.IsFalse(typeof(IList<IntValue>).IsSubTypeOf(typeof(IList<IItem>)));
    50       Assert.IsTrue(typeof(List<IItem>).IsSubTypeOf(typeof(IList<IItem>)));
    51       Assert.IsFalse(typeof(ItemList<>).IsSubTypeOf(typeof(IList<IItem>)));
    52       Assert.IsFalse(typeof(ItemList<>).IsSubTypeOf(typeof(List<IItem>)));
     50      Assert.IsTrue(typeof(List<IItem>).IsAssignableTo(typeof(IList<IItem>)));
     51      Assert.IsFalse(typeof(IList<IntValue>).IsAssignableTo(typeof(IList<IItem>)));
     52      Assert.IsTrue(typeof(List<IItem>).IsAssignableTo(typeof(IList<IItem>)));
     53      Assert.IsFalse(typeof(ItemList<>).IsAssignableTo(typeof(IList<IItem>)));
     54      Assert.IsFalse(typeof(ItemList<>).IsAssignableTo(typeof(List<IItem>)));
    5355
    54       Assert.IsFalse(typeof(List<int>).IsSubTypeOf(typeof(List<>)));
    55       Assert.IsTrue(typeof(List<>).IsSubTypeOf(typeof(IList<>)));
    56       Assert.IsTrue(typeof(ItemList<>).IsSubTypeOf(typeof(IList<>)));
    57       Assert.IsTrue(typeof(NamedItemCollection<>).IsSubTypeOf(typeof(IItemCollection<>)));
    58       Assert.IsFalse(typeof(List<IntValue>).IsSubTypeOf(typeof(IList<>)));
     56      Assert.IsTrue(typeof(List<int>).IsAssignableTo(typeof(List<>)));
     57      Assert.IsTrue(typeof(List<>).IsAssignableTo(typeof(IList<>)));
     58      Assert.IsTrue(typeof(ItemList<>).IsAssignableTo(typeof(IList<>)));
     59      Assert.IsTrue(typeof(NamedItemCollection<>).IsAssignableTo(typeof(IItemCollection<>)));
     60      Assert.IsTrue(typeof(List<IntValue>).IsAssignableTo(typeof(IList<>)));
    5961    }
    6062
Note: See TracChangeset for help on using the changeset viewer.