/* * Copyright 2013 Guidewire Software, Inc. */ package gw.plugin.ij.usages; import com.google.common.collect.ImmutableList; import com.google.common.collect.Sets; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.util.Computable; import com.intellij.pom.PomTarget; import com.intellij.psi.PsiClass; import com.intellij.psi.PsiMethod; import com.intellij.psi.targets.AliasingPsiTarget; import com.intellij.psi.targets.AliasingPsiTargetMapper; import gw.lang.parser.Keyword; import gw.lang.reflect.TypeSystem; import gw.lang.reflect.module.IModule; import gw.plugin.ij.lang.psi.api.statements.typedef.IGosuMethod; import gw.plugin.ij.util.GosuModuleUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Set; public class GosuAliasingPsiTargetMapper implements AliasingPsiTargetMapper { private Set<AliasingPsiTarget> getMethodTargets(@NotNull final PsiMethod method) { return ApplicationManager.getApplication().runReadAction(new Computable<Set<AliasingPsiTarget>>() { @Override public Set<AliasingPsiTarget> compute() { final List<String> aliasNames; if (method.isConstructor()) { aliasNames = ImmutableList.of(Keyword.KW_construct.getName(), Keyword.KW_this.getName(), Keyword.KW_super.getName()); } else { aliasNames = getGosuPropertyNames(method); } final Set<AliasingPsiTarget> aliases = Sets.newHashSet(); for (String propName : aliasNames) { final GosuAliasingPsiTarget alias = new GosuAliasingPsiTarget(method); alias.setName(propName); aliases.add(alias); } return aliases; } }); } private Set<AliasingPsiTarget> getClassTargets(@NotNull final PsiClass klass) { final String qualifiedName = ApplicationManager.getApplication().runReadAction(new Computable<String>() { @Nullable public String compute() { return klass.getQualifiedName(); } }); IModule rootModule = GosuModuleUtil.getGlobalModule(klass.getProject()); TypeSystem.pushModule( rootModule ); try { final Set<AliasingPsiTarget> aliases = Sets.newHashSet(); if (TypeSystem.getDefaultType().getType().getName().equals(qualifiedName)) { final GosuAliasingPsiTarget alias = new GosuAliasingPsiTarget(klass); alias.setName("Type"); aliases.add(alias); } return aliases; } finally { TypeSystem.popModule( rootModule ); } } @NotNull @Override public Set<AliasingPsiTarget> getTargets(@NotNull final PomTarget target) { if (target instanceof PsiMethod) { return getMethodTargets((PsiMethod) target); } else if (target instanceof PsiClass) { return getClassTargets((PsiClass) target); } return Collections.emptySet(); } // TODO: use GosuProperties class here somehow @NotNull public static List<String> getGosuPropertyNames(@NotNull final PsiMethod method) { List<String> propNames = new ArrayList<>(); String name = method.getName(); int nameLen = name.length(); String returnTypeName = ApplicationManager.getApplication().runReadAction(new Computable<String>() { @Override public String compute() { return method.getReturnType().getCanonicalText(); } }); if (nameLen > 3 && name.startsWith("get") && !returnTypeName.equals("void") && method.getParameterList().getParametersCount() == 0) { propNames.add(name.substring(3)); propNames.add("is" + name.substring(3)); } else if (nameLen > 3 && name.startsWith("set") && returnTypeName.equals("void") && method.getParameterList().getParametersCount() == 1) { propNames.add(name.substring(3)); } else if (nameLen > 2 && name.startsWith("is") && (returnTypeName.equals("boolean") || returnTypeName.equals("java.lang.Boolean")) && method.getParameterList().getParametersCount() == 0) { propNames.add(name.substring(2)); propNames.add("get" + name.substring(2)); } else if (method instanceof IGosuMethod && ((IGosuMethod) method).isForProperty()) { if (returnTypeName.equals("void")) { propNames.add("set" + name); } else { propNames.add("get" + name); propNames.add("is" + name); } } return propNames; } }