public void resolveGroup()

in base/src/main/java/org/arend/naming/resolving/visitor/DefinitionResolveNameVisitor.java [790:1001]


  public void resolveGroup(Group group, Scope scope) {
    LocatedReferable groupRef = group.getReferable();
    Collection<? extends Statement> statements = group.getStatements();
    Collection<? extends Group> dynamicSubgroups = group.getDynamicSubgroups();

    var def = myConcreteProvider.getConcrete(groupRef);
    Scope cachedScope = CachingScope.make(makeScope(group, scope, def instanceof Concrete.ClassDefinition ? LexicalScope.Extent.EXTERNAL_AND_FIELDS : LexicalScope.Extent.EVERYTHING));
    if (def instanceof Concrete.ClassDefinition) {
      resolveSuperClasses((Concrete.ClassDefinition) def, new PrivateFilteredScope(cachedScope), false);
    }
    if (def instanceof Concrete.ResolvableDefinition) {
      ((Concrete.ResolvableDefinition) def).accept(this, cachedScope);
    } else {
      myLocalErrorReporter = new LocalErrorReporter(groupRef, myErrorReporter);
    }
    if (def instanceof Concrete.Definition && !myExternalParameters.isEmpty()) {
      ((Concrete.Definition) def).setExternalParameters(new HashMap<>(myExternalParameters));
    }

    if (def instanceof Concrete.ClassDefinition && (!statements.isEmpty() || !dynamicSubgroups.isEmpty())) {
      cachedScope = CachingScope.make(makeScope(group, scope, LexicalScope.Extent.EVERYTHING));
    }
    boolean added = addExternalParameters(def);
    for (Statement statement : statements) {
      Group subgroup = statement.getGroup();
      if (subgroup != null) {
        resolveGroup(subgroup, cachedScope);
      }
    }
    for (Group subgroup : dynamicSubgroups) {
      resolveGroup(subgroup, cachedScope);
    }
    if (added) {
      assert def != null;
      myExternalParameters.remove((TCDefReferable) def.getData());
    }

    if (myResolveTypeClassReferences) {
      return;
    }

    myLocalErrorReporter = myErrorReporter;

    boolean isTopLevel = !(group instanceof ChildGroup) || ((ChildGroup) group).getParentGroup() == null;
    boolean hasNamespaceCommands = false;
    for (Statement statement : statements) {
      NamespaceCommand namespaceCommand = statement.getNamespaceCommand();
      if (namespaceCommand == null) {
        continue;
      }
      hasNamespaceCommands = true;
      List<String> path = namespaceCommand.getPath();
      NamespaceCommand.Kind kind = namespaceCommand.getKind();
      if (path.isEmpty() || kind == NamespaceCommand.Kind.IMPORT && !isTopLevel) {
        continue;
      }

      LongUnresolvedReference reference = new LongUnresolvedReference(namespaceCommand, path);
      Scope importedScope = kind == NamespaceCommand.Kind.IMPORT ? cachedScope.getImportedSubscope() : cachedScope;
      List<Referable> resolvedRefs = myResolverListener == null ? null : new ArrayList<>();
      reference.resolve(importedScope, resolvedRefs);
      if (myResolverListener != null) {
        myResolverListener.namespaceResolved(namespaceCommand, resolvedRefs);
      }
      Scope curScope = reference.resolveNamespace(importedScope);
      if (curScope == null) {
        myLocalErrorReporter.report(reference.getErrorReference().getError());
      }

      if (curScope != null) {
        for (NameRenaming renaming : namespaceCommand.getOpenedReferences()) {
          Referable oldRef = renaming.getOldReference();
          Referable ref = ExpressionResolveNameVisitor.resolve(oldRef, new PrivateFilteredScope(curScope, true), null);
          if (myResolverListener != null) {
            myResolverListener.renamingResolved(renaming, oldRef, ref);
          }
          if (ref instanceof ErrorReference) {
            myLocalErrorReporter.report(((ErrorReference) ref).getError());
          }
        }

        curScope = NamespaceCommandNamespace.makeNamespace(curScope, new NamespaceCommand() {
          @NotNull
          @Override
          public Kind getKind() {
            return namespaceCommand.getKind();
          }

          @NotNull
          @Override
          public List<String> getPath() {
            return namespaceCommand.getPath();
          }

          @Override
          public boolean isUsing() {
            return namespaceCommand.isUsing();
          }

          @NotNull
          @Override
          public Collection<? extends NameRenaming> getOpenedReferences() {
            return namespaceCommand.getOpenedReferences();
          }

          @NotNull
          @Override
          public Collection<? extends Referable> getHiddenReferences() {
            return Collections.emptyList();
          }
        });

        for (Referable ref : namespaceCommand.getHiddenReferences()) {
          ref = ExpressionResolveNameVisitor.resolve(ref, new PrivateFilteredScope(curScope, true), null);
          if (ref instanceof ErrorReference) {
            myLocalErrorReporter.report(((ErrorReference) ref).getError());
          }
        }
      }
    }

    // Some checks

    Collection<? extends Group.InternalReferable> fields = group.getFields();
    if (!fields.isEmpty()) {
      Map<String, Pair<LocatedReferable, ClassReferable>> superFields = collectClassFields(groupRef);
      for (Group.InternalReferable internalRef : fields) {
        checkField(internalRef.getReferable(), superFields);
      }
    }

    Map<String, LocatedReferable> referables = new HashMap<>();
    for (Group.InternalReferable internalRef : group.getInternalReferables()) {
      LocatedReferable ref = internalRef.getReferable();
      String name = ref.textRepresentation();
      if (!name.isEmpty() && !"_".equals(name)) {
        referables.putIfAbsent(name, ref);
      }
    }

    for (Statement statement : statements) {
      Group subgroup = statement.getGroup();
      if (subgroup != null) {
        checkReference(subgroup.getReferable(), referables, false);
      }
    }

    for (Group subgroup : dynamicSubgroups) {
      checkReference(subgroup.getReferable(), referables, false);
    }

    for (Group subgroup : dynamicSubgroups) {
      checkSubgroup(subgroup, referables);
    }

    for (Statement statement : statements) {
      Group subgroup = statement.getGroup();
      if (subgroup != null) {
        checkSubgroup(subgroup, referables);
      }
    }

    if (!hasNamespaceCommands) {
      return;
    }

    List<Pair<NamespaceCommand, Map<String, Referable>>> namespaces = new ArrayList<>();
    for (Statement statement : statements) {
      NamespaceCommand cmd = statement.getNamespaceCommand();
      if (cmd == null) {
        continue;
      }
      if (!isTopLevel && cmd.getKind() == NamespaceCommand.Kind.IMPORT) {
        myLocalErrorReporter.report(new ParsingError(ParsingError.Kind.MISPLACED_IMPORT, cmd));
      } else {
        checkNamespaceCommand(cmd, referables.keySet());
      }
      Collection<? extends Referable> elements = NamespaceCommandNamespace.resolveNamespace(cmd.getKind() == NamespaceCommand.Kind.IMPORT ? cachedScope.getImportedSubscope() : cachedScope, cmd).getElements(null);
      if (!elements.isEmpty()) {
        Map<String, Referable> map = new LinkedHashMap<>();
        for (Referable element : elements) {
          map.put(element.getRefName(), element);
        }
        namespaces.add(new Pair<>(cmd, map));
      }
    }

    for (int i = 0; i < namespaces.size(); i++) {
      Pair<NamespaceCommand, Map<String, Referable>> pair = namespaces.get(i);
      for (Map.Entry<String, Referable> entry : pair.proj2.entrySet()) {
        if (referables.containsKey(entry.getKey())) {
          continue;
        }

        for (int j = i + 1; j < namespaces.size(); j++) {
          Referable ref = namespaces.get(j).proj2.get(entry.getKey());
          if (ref != null && !ref.equals(entry.getValue())) {
            NamespaceCommand nsCmd = namespaces.get(j).proj1;
            Object cause = nsCmd;
            for (NameRenaming renaming : nsCmd.getOpenedReferences()) {
              String name = renaming.getName();
              if (entry.getKey().equals(name != null ? name : renaming.getOldReference().textRepresentation())) {
                cause = renaming;
                break;
              }
            }
            myLocalErrorReporter.report(new DuplicateOpenedNameError(ref, pair.proj1, cause));
          }
        }
      }
    }
  }