package com.reason.lang.core.psi.impl;

import com.intellij.extapi.psi.StubBasedPsiElementBase;
import com.intellij.lang.ASTNode;
import com.intellij.navigation.ItemPresentation;
import com.intellij.psi.PsiElement;
import com.intellij.psi.stubs.IStubElementType;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.util.IncorrectOperationException;
import com.reason.icons.Icons;
import com.reason.lang.core.ModulePath;
import com.reason.lang.core.psi.*;
import com.reason.lang.core.stub.ModuleStub;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import javax.swing.*;
import java.util.Collection;
import java.util.Collections;

public class PsiModuleImpl extends StubBasedPsiElementBase<ModuleStub> implements PsiModule {

    private ModulePath m_modulePath;

    //region Constructors
    public PsiModuleImpl(ASTNode node) {
        super(node);
    }

    public PsiModuleImpl(ModuleStub stub, IStubElementType nodeType) {
        super(stub, nodeType);
    }
    //endregion

    //region NamedElement
    @Override
    public String getName() {
        PsiElement nameIdentifier = getNameIdentifier();
        return nameIdentifier == null ? "" : nameIdentifier.getText();
    }

    @Nullable
    @Override
    public PsiElement getNameIdentifier() {
        return findChildByClass(PsiModuleName.class);
    }

    @Override
    public PsiElement setName(@NotNull String name) throws IncorrectOperationException {
        return this; // Use PsiModuleReference.handleElementRename()
    }
    //endregion

    @Nullable
    public PsiScopedExpr getBody() {
        return findChildByClass(PsiScopedExpr.class);
    }

    @Nullable
    public PsiSignature getSignature() {
        return findChildByClass(PsiSignature.class);
    }

    @Override
    public Collection<PsiLet> getLetExpressions() {
        PsiScopedExpr body = getBody();
        return body == null ? Collections.emptyList() : PsiTreeUtil.findChildrenOfType(body, PsiLet.class);
    }

    @Override
    public Collection<PsiType> getTypeExpressions() {
        PsiScopedExpr body = getBody();
        return body == null ? Collections.emptyList() : PsiTreeUtil.findChildrenOfType(body, PsiType.class);
    }

    @Override
    public Collection<PsiNamedElement> getExpressions() {
        PsiScopedExpr body = getBody();
        return body == null ? Collections.emptyList() : PsiTreeUtil.findChildrenOfAnyType(body, PsiType.class, PsiModule.class, PsiLet.class);
    }

    public ItemPresentation getPresentation() {
        return new ItemPresentation() {
            @Nullable
            @Override
            public String getPresentableText() {
                return getName();
            }

            @Nullable
            @Override
            public String getLocationString() {
                return null;
            }

            @Nullable
            @Override
            public Icon getIcon(boolean unused) {
                return Icons.MODULE;
            }
        };
    }

    @NotNull
    @Override
    public ModulePath getQPath() {
        //if (m_modulePath == null) {
        //    List<PsiElement> parents = new ArrayList<>();
        //
        //    PsiModule parent = PsiTreeUtil.getParentOfType(this, PsiModule.class);
        //    while (parent != null) {
        //        parents.add(parent);
        //        parent = PsiTreeUtil.getParentOfType(this, PsiModule.class);
        //    }
        //
        //    parents.add(getContainingFile());
        //    Collections.reverse(parents);
        //    m_modulePath = new ModulePath(parents);
        //}
        //
        //return m_modulePath;
        return new ModulePath(new String[]{"M"});
    }

    @Override
    public String toString() {
        return "Module(" + getName() + ")";
    }
}

@@ -607,24 +607,52 @@
 ax.swing.*;%0A
+import java.util.ArrayList;%0A
 import java.
@@ -697,16 +697,39 @@
 ections;
+%0Aimport java.util.List;
 %0A%0Apublic
@@ -3141,18 +3141,16 @@
         
-//
 if (m_mo
@@ -3173,26 +3173,24 @@
 ) %7B%0A        
-//
     List%3CPsi
@@ -3227,26 +3227,16 @@
 st%3C%3E();%0A
-        //
 %0A       
@@ -3232,26 +3232,24 @@
 );%0A%0A        
-//
     PsiModul
@@ -3315,26 +3315,24 @@
 s);%0A        
-//
     while (p
@@ -3348,34 +3348,32 @@
 null) %7B%0A        
-//
         parents.
@@ -3389,26 +3389,24 @@
 t);%0A        
-//
         pare
@@ -3430,36 +3430,38 @@
 getParentOfType(
-this
+parent
 , PsiModule.clas
@@ -3476,26 +3476,14 @@
     
-//
     %7D%0A
-        //
 %0A   
@@ -3483,26 +3483,24 @@
  %7D%0A%0A        
-//
     parents.
@@ -3529,26 +3529,24 @@
 ));%0A        
-//
     Collecti
@@ -3575,18 +3575,16 @@
         
-//
     m_mo
@@ -3631,22 +3631,10 @@
     
-//%7D%0A        //
+%7D%0A
 %0A   
@@ -3638,18 +3638,16 @@
         
-//
 return m
@@ -3663,58 +3663,8 @@
 th;%0A
-        return new ModulePath(new String%5B%5D%7B%22M%22%7D);%0A
     

Fix an infinite loop !!