package jetbrains.mps.idea.java.psiStubs; /*Generated by MPS */ import jetbrains.mps.idea.core.refactoring.NodePtr; import com.intellij.psi.PsiElement; import jetbrains.mps.smodel.SNodeId; import org.jetbrains.mps.openapi.model.SModelReference; import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.NotNull; import com.intellij.psi.PsiFile; import com.intellij.psi.PsiJavaFile; import org.jetbrains.mps.openapi.module.SModule; import com.intellij.openapi.project.Project; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.openapi.module.Module; import com.intellij.openapi.module.ModuleManager; import jetbrains.mps.idea.core.facet.MPSFacet; import com.intellij.facet.FacetManager; import jetbrains.mps.idea.core.facet.MPSFacetType; import com.intellij.util.xml.ModuleContentRootSearchScope; import jetbrains.mps.java.stub.JavaPackageNameStub; import jetbrains.mps.smodel.SModelId; import com.intellij.psi.PsiClass; import com.intellij.psi.PsiField; import com.intellij.psi.PsiNamedElement; import com.intellij.psi.PsiMethod; import com.intellij.psi.PsiParameter; import com.intellij.psi.PsiTypeElement; import com.intellij.psi.PsiType; public class JavaForeignIdBuilder { public static NodePtr computeNodePtr(PsiElement element) { SNodeId nodeId = computeNodeId(element); SModelReference modelRef = computeModelReference(element); if (nodeId == null || modelRef == null) { return null; } return new NodePtr(modelRef, nodeId); } @Nullable public static SNodeId.Foreign computeNodeId(@NotNull PsiElement element) { PsiElement parent = element.getParent(); String prefix; if (parent instanceof PsiFile) { // element is root prefix = SNodeId.Foreign.ID_PREFIX; } else { org.jetbrains.mps.openapi.model.SNodeId parentId = computeNodeId(parent); if (parentId == null) { return null; } prefix = parentId.toString() + "."; } // e.g. this was an anonymous class and we don't compute nodeId for parent if (prefix == null) { return null; } return computeNodeId(prefix, element); } @Nullable public static SModelReference computeModelReference(PsiElement element) { PsiFile file = element.getContainingFile(); if (!(file instanceof PsiJavaFile)) { return null; } String packageName = ((PsiJavaFile) file).getPackageName(); // we want to know mps module id SModule mpsModule = null; Project project = element.getProject(); VirtualFile vfile = file.getVirtualFile(); // MPS-17704: there was situation when an element with null virtual file came from MPSReferenceSearch // element was the target of search if (vfile == null) { return null; } for (Module module : ModuleManager.getInstance(project).getModules()) { MPSFacet facet = FacetManager.getInstance(module).getFacetByType(MPSFacetType.ID); if (facet == null) { continue; } if (new ModuleContentRootSearchScope(module).contains(vfile)) { mpsModule = facet.getSolution(); break; } } if (mpsModule == null) { return null; } return new JavaPackageNameStub(packageName).asModelReference(mpsModule.getModuleReference()); } /*package*/ static jetbrains.mps.smodel.SModelReference computeModelReference(String packageName, String mpsModuleId) { String stereotype = "java_stub"; if (packageName.length() == 0) { packageName = "<default package>"; } SModelId modelId = SModelId.foreign(stereotype, packageName); return new jetbrains.mps.smodel.SModelReference(null, modelId, packageName + "@" + stereotype); } /*package*/ static SNodeId.Foreign computeNodeId(String prefix, PsiElement element) { StringBuilder sb = new StringBuilder(prefix); if (element instanceof PsiClass || element instanceof PsiField) { // simply take the name String name = ((PsiNamedElement) element).getName(); if (name == null) { return null; } sb.append(name); } else if (element instanceof PsiMethod) { PsiMethod method = (PsiMethod) element; String name = method.getName(); if (name == null) { return null; } if (((PsiMethod) element).isConstructor()) { sb.deleteCharAt(sb.length() - 1); } else { sb.append(name); } sb.append('('); for (PsiParameter param : method.getParameterList().getParameters()) { // for classess we want their name exactly how it is written in the source file // (either short name, partially qualified or fully qualified) // to make it equal to what we have in eclipse stubs PsiTypeElement psiTypeElem = param.getTypeElement(); PsiType psiType = param.getType(); if (psiType != null && psiTypeElem != null) { sb.append(ASTConverter.typeReferenceId(psiTypeElem)); sb.append(','); } } int last = sb.length() - 1; if (sb.charAt(last) == ',') { sb.deleteCharAt(last); } sb.append(')'); } return new SNodeId.Foreign(sb.toString()); } }