private void initializeExplicitConstructor(
     TurinTypeContructorDefinitionNode constructor, SymbolResolver resolver) {
   List<? extends FormalParameter> allParams = constructor.getParameters();
   List<FormalParameter> paramsWithoutDefaultValues =
       allParams
           .stream()
           .filter((p) -> !p.hasDefaultValue())
           .collect(Collectors.<FormalParameter>toList());
   List<String> paramSignatures =
       paramsWithoutDefaultValues
           .stream()
           .map((p) -> p.getType().jvmType().getSignature())
           .collect(Collectors.toList());
   boolean hasDefaultParameters =
       allParams.stream().filter((p) -> p.hasDefaultValue()).findFirst().isPresent();
   if (hasDefaultParameters) {
     paramSignatures.add("Ljava/util/Map;");
   }
   JvmConstructorDefinition constructorDefinition =
       new JvmConstructorDefinition(
           jvmType().getInternalName(), "(" + String.join("", paramSignatures) + ")V");
   constructors.add(
       new InternalConstructorDefinition(
           new ReferenceTypeUsage(this), allParams, constructorDefinition));
 }
 public List<TurinTypeMethodDefinitionNode> getDirectMethods() {
   List<TurinTypeMethodDefinitionNode> methods = new ArrayList<>();
   for (Node member : members) {
     if (member instanceof TurinTypeMethodDefinitionNode) {
       methods.add((TurinTypeMethodDefinitionNode) member);
     }
   }
   return methods;
 }
 public InternalConstructorDefinition getOnlyConstructor(SymbolResolver resolver) {
   if (constructors == null) {
     initializeConstructors(resolver);
   }
   if (constructors.size() != 1) {
     throw new IllegalStateException();
   }
   return constructors.get(0);
 }
 @Override
 public List<ReferenceTypeUsage> getAllAncestors() {
   if (getBaseType().isPresent()) {
     List<ReferenceTypeUsage> res = new ArrayList<>();
     res.add(getBaseType().get().asReferenceTypeUsage());
     res.addAll(getBaseType().get().asReferenceTypeUsage().getAllAncestors());
     return res;
   }
   return ImmutableList.of(ReferenceTypeUsage.OBJECT(symbolResolver()));
 }
 public List<Property> getDirectProperties(SymbolResolver resolver) {
   List<Property> properties = new ArrayList<>();
   for (Node member : members) {
     if (member instanceof PropertyDefinition) {
       properties.add(Property.fromDefinition((PropertyDefinition) member));
     } else if (member instanceof PropertyReference) {
       properties.add(Property.fromReference((PropertyReference) member, resolver));
     }
   }
   return properties;
 }
 @Override
 public Iterable<Node> getChildren() {
   List<Node> children = new LinkedList<>();
   children.addAll(members);
   children.addAll(annotations);
   if (baseType.isPresent()) {
     children.add(baseType.get());
   }
   children.addAll(interfaces);
   return children;
 }
 public List<TurinTypeContructorDefinitionNode> getExplicitConstructors() {
   return members
       .stream()
       .filter((m) -> m instanceof TurinTypeContructorDefinitionNode)
       .map((m) -> (TurinTypeContructorDefinitionNode) m)
       .collect(Collectors.toList());
 }
 public void add(PropertyDefinition propertyDefinition) {
   if (propertyDefinition.getType().getParent() != propertyDefinition
       && propertyDefinition.getType().getParent().getParent() == null) {
     throw new IllegalArgumentException();
   }
   members.add(propertyDefinition);
   propertyDefinition.parent = this;
 }
 @Override
 public JvmMethodDefinition findMethodFor(
     String methodName, List<JvmType> actualParams, boolean staticContext) {
   ensureIsInitialized(symbolResolver());
   List<InternalMethodDefinition> methods = methodsByName.get(methodName);
   if (methods.size() == 0) {
     throw new IllegalArgumentException("No method found with name " + methodName);
   } else if (methods.size() == 1) {
     if (methods.get(0).matchJvmTypes(symbolResolver(), actualParams)) {
       return methods.get(0).getJvmMethodDefinition();
     } else {
       throw new IllegalArgumentException(
           "No method found with name " + methodName + " which matches " + actualParams);
     }
   } else {
     throw new IllegalStateException("No overloaded methods should be present in Turin types");
   }
 }
  @Override
  public boolean equals(Object o) {
    if (this == o) return true;
    if (o == null || getClass() != o.getClass()) return false;

    TurinTypeDefinition that = (TurinTypeDefinition) o;

    if (!members.equals(that.members)) return false;
    if (!name.equals(that.name)) return false;

    return true;
  }
  @Override
  public JvmConstructorDefinition resolveConstructorCall(List<ActualParam> actualParams) {
    // all named parameters should be after the named ones
    if (!ParamUtils.verifyOrder(actualParams)) {
      throw new IllegalArgumentException(
          "Named params should all be grouped after the positional ones");
    }

    ensureIsInitialized(symbolResolver());
    Optional<InternalConstructorDefinition> constructor =
        constructors.stream().filter((c) -> c.match(symbolResolver(), actualParams)).findFirst();

    if (!constructor.isPresent()) {
      throw new UnsolvedConstructorException(getQualifiedName(), actualParams);
    }

    return constructor.get().getJvmConstructorDefinition();
  }
 private boolean isDefiningMethod(
     String name, List<TypeUsage> paramTypes, SymbolResolver resolver) {
   return getDirectMethods()
           .stream()
           .filter((m) -> m.getName().equals(name))
           .filter(
               (m) ->
                   m.getParameters()
                       .stream()
                       .map((p) -> p.calcType().jvmType())
                       .collect(Collectors.toList())
                       .equals(
                           paramTypes
                               .stream()
                               .map((p) -> p.jvmType())
                               .collect(Collectors.toList())))
           .count()
       > 0;
 }
  private void initializeImplicitConstructor(SymbolResolver resolver) {
    List<? extends FormalParameter> inheritedParams = Collections.emptyList();
    if (getBaseType().isPresent()) {
      List<InternalConstructorDefinition> constructors =
          getBaseType().get().asReferenceTypeUsage().getTypeDefinition().getConstructors();
      if (constructors.size() != 1) {
        throw new UnsupportedOperationException();
      }
      inheritedParams = constructors.get(0).getFormalParameters();
    }

    List<FormalParameterNode> newParams =
        this.assignableProperties(resolver)
            .stream()
            .map(
                (p) ->
                    new FormalParameterNode(
                        p.getTypeUsage().copy(), p.getName(), p.getDefaultValue()))
            .collect(Collectors.toList());
    List<FormalParameter> allParams = new LinkedList<>();
    allParams.addAll(inheritedParams);
    allParams.addAll(newParams);
    allParams.sort(
        new Comparator<FormalParameter>() {
          @Override
          public int compare(FormalParameter o1, FormalParameter o2) {
            return Boolean.compare(o1.hasDefaultValue(), o2.hasDefaultValue());
          }
        });
    for (FormalParameter p : allParams) {
      // needed to solve symbols
      if (p.isNode()) {
        p.asNode().setParent(this);
      }
    }
    addConstructorWithParams(allParams, resolver);
  }
 public void addAnnotation(AnnotationUsage annotation) {
   annotation.setParent(this);
   annotations.add(annotation);
 }
 public void addInterface(TypeUsageNode interfaze) {
   interfaze.setParent(this);
   interfaces.add(interfaze);
 }
 public void add(TurinTypeContructorDefinitionNode contructorDefinition) {
   members.add(contructorDefinition);
   contructorDefinition.parent = this;
 }
 public void add(TurinTypeMethodDefinitionNode methodDefinition) {
   members.add(methodDefinition);
   methodDefinition.parent = this;
 }
 public void add(PropertyReference propertyReference) {
   members.add(propertyReference);
   propertyReference.parent = this;
 }
 @Override
 public int hashCode() {
   int result = name.hashCode();
   result = 31 * result + members.hashCode();
   return result;
 }