All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.aya.resolve.context.Candidate Maven / Gradle / Ivy

There is a newer version: 0.36.0
Show newest version
// Copyright (c) 2020-2024 Tesla (Yinsen) Zhang.
// Use of this source code is governed by the MIT license that can be found in the LICENSE.md file.
package org.aya.resolve.context;

import kala.collection.CollectionView;
import kala.collection.SeqView;
import kala.collection.immutable.ImmutableMap;
import kala.collection.immutable.ImmutableSeq;
import kala.collection.mutable.MutableMap;
import org.aya.syntax.concrete.stmt.ModuleName;
import org.aya.util.error.Panic;
import org.jetbrains.annotations.NotNull;

/**
 * Candidate represents a list of candidate of symbol resolving
 */
public sealed interface Candidate {
  /**
   * Merge two candidate.
   *
   * @implSpec If conflict happens, {@param candy} will overwrite {@code this},
   * the user should check all possible conflicts before merge.
   */
  @NotNull Candidate merge(@NotNull Candidate candy);
  boolean isAmbiguous();
  boolean isEmpty();
  @NotNull ImmutableSeq from();
  boolean contains(@NotNull ModuleName modName);

  static  @NotNull Candidate of(@NotNull ModuleName fromModule, @NotNull T symbol) {
    return switch (fromModule) {
      case ModuleName.Qualified qualified -> Imported.of(qualified, symbol);
      case ModuleName.ThisRef _ -> new Defined<>(symbol);
    };
  }

  /**
   * Returns the only symbol in this candidate, should check {@link #isEmpty()} and {@link #isAmbiguous()} first.
   *
   * @return the only symbol in this candidate, exception if this candidate {@link #isEmpty()} or {@link #isAmbiguous()}
   */
  T get();

  CollectionView getAll();

  /**
   * A candidate list that only store one symbol, furthermore, it implies the symbol is defined in this module.
   */
  record Defined(T symbol) implements Candidate {
    @Override public @NotNull Candidate merge(@NotNull Candidate symbol) {
      return symbol instanceof Candidate.Defined defined ? defined : this;
    }

    @Override public boolean isAmbiguous() { return false; }
    @Override public boolean isEmpty() { return false; }
    @Override public T get() { return symbol; }

    @Override
    public CollectionView getAll() {
      return SeqView.of(symbol);
    }
    @Override public @NotNull ImmutableSeq from() { return ImmutableSeq.of(ModuleName.This); }
    @Override public boolean contains(@NotNull ModuleName modName) { return modName == ModuleName.This; }
  }

  /**
   * Default candidate, it represents a candidate list that is imported from other module
   *
   * @param symbols key: the module that the symbol comes from
* value: the symbol */ record Imported(@NotNull ImmutableMap symbols) implements Candidate { public static @NotNull Candidate empty() { return new Imported<>(ImmutableMap.empty()); } public static @NotNull Candidate of(@NotNull ModuleName.Qualified from, @NotNull T symbol) { return new Imported<>(ImmutableMap.of(from, symbol)); } @Override public boolean isAmbiguous() { return symbols.valuesView().distinct().sizeGreaterThan(1); } @Override public boolean isEmpty() { return symbols.isEmpty(); } @Override public T get() { var view = symbols.valuesView().distinct(); if (view.sizeGreaterThan(1)) Panic.unreachable(); //noinspection OptionalGetWithoutIsPresent return symbols.valuesView().stream().findFirst().get(); } @Override public CollectionView getAll() { return symbols.valuesView(); } @Override public @NotNull ImmutableSeq from() { return ImmutableSeq.from(symbols.keysView()); } @Override public boolean contains(@NotNull ModuleName modName) { return modName instanceof ModuleName.Qualified qmod && symbols.containsKey(qmod); } @Override public @NotNull Candidate merge(@NotNull Candidate candy) { return switch (candy) { case Candidate.Defined v -> v; case Candidate.Imported imported -> { var symbols = MutableMap.create(); symbols.putAll(this.symbols); symbols.putAll(imported.symbols); yield new Imported<>(ImmutableMap.from(symbols)); } }; } } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy