package org.fandev.lang.fan.psi.impl;
import com.intellij.extapi.psi.PsiFileBase;
import com.intellij.openapi.fileTypes.FileType;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.FileViewProvider;
import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiDirectory;
import com.intellij.psi.PsiFile;
import com.intellij.util.IncorrectOperationException;
import org.fandev.lang.fan.FanSupportLoader;
import org.fandev.lang.fan.psi.FanFile;
import org.fandev.lang.fan.psi.api.statements.typeDefs.FanClassDefinition;
import org.fandev.lang.fan.psi.api.statements.typeDefs.FanTypeDefinition;
import org.fandev.lang.fan.psi.api.statements.typeDefs.members.FanMethod;
import org.fandev.lang.fan.psi.api.statements.FanTopLevelDefintion;
import org.fandev.module.pod.PodModel;
import org.fandev.utils.VirtualFileUtil;
import org.jetbrains.annotations.NotNull;
/**
* @author Dror Bereznitsky
* @date Jan 7, 2009 2:50:33 PM
*/
public class FanFileImpl extends PsiFileBase implements FanFile {
private String podName;
private final static Logger logger = Logger.getInstance("org.fandev.lang.fan.psi.impl.FanFileImpl");
public FanFileImpl(final FileViewProvider fileViewProvider) {
super(fileViewProvider, FanSupportLoader.FAN.getLanguage());
}
@NotNull
public FileType getFileType() {
return FanSupportLoader.FAN;
}
public String getPodName() {
if (podName != null) {
return podName;
}
// If I'm a build.fan get it
if (PodModel.BUILD_FAN.equals(getName())) {
// Ugly Hack until we can execute Fan script (TODO: use the PodFileParser)
final FanClassDefinition[] classDef = this.findChildrenByClass(FanClassDefinition.class);
if (classDef.length > 0) {
final FanMethod[] methods = classDef[0].getFanMethods();
if (methods.length > 0) {
for (final FanMethod method : methods) {
// TODO: Even uglier hack until we have Expression parsing
if (method.getName().equals("setup")) {
final String setupBody = method.getBody().getText();
final int podNameIdx = setupBody.indexOf("podName");
if (podNameIdx != -1) {
final int firstDQ = setupBody.indexOf('"', podNameIdx+"podName".length()+1);
final int lastDQ = setupBody.indexOf('"', firstDQ+1);
podName = setupBody.substring(firstDQ+1,lastDQ);
return podName;
}
}
}
}
}
logger.warn("Did not find pod name in " + (getVirtualFile() != null ? getVirtualFile().getPath() : this.toString()));
return "NotFound";
}
// If the file is inside a pod
final VirtualFile myVirtualFile = getVirtualFile();
if (myVirtualFile != null && myVirtualFile.getUrl().contains(".pod")) {
final String url = myVirtualFile.getUrl();
final String podPath = url.substring(0, url.indexOf(".pod"));
int podNameStartIndex = podPath.lastIndexOf(VirtualFileUtil.VFS_PATH_SEPARATOR);
podNameStartIndex = podNameStartIndex < 0 ? 0 : podNameStartIndex + 1;
podName = podPath.substring(podNameStartIndex);
return podName;
}
// Go up until the directory contain a build.fan file
PsiDirectory psiDirectory = getParent();
int upMax = 4;
while (psiDirectory != null && upMax > 0) {
final PsiFile[] files = psiDirectory.getFiles();
if (files != null) {
for (final PsiFile file : files) {
if (PodModel.BUILD_FAN.equals(file.getName())) {
podName = ((FanFile)file).getPodName();
return podName;
}
}
}
psiDirectory = psiDirectory.getParentDirectory();
upMax--;
}
return "NotFound";
}
public FanTypeDefinition[] getTypeDefinitions() {
return findChildrenByClass(FanTypeDefinition.class);
}
public FanTypeDefinition getTypeByName(String name) {
for (final FanTypeDefinition typeDef : getTypeDefinitions()) {
if (name.equals(typeDef.getName())) {
return typeDef;
}
}
return null;
}
@NotNull
public PsiClass[] getClasses() {
return getTypeDefinitions();
}
public String getPackageName() {
return podName;
}
public void setPackageName(final String s) throws IncorrectOperationException {
podName = s;
}
public FanTopLevelDefintion[] getTopLevelDefinitions() {
return findChildrenByClass(FanTopLevelDefintion.class);
}
}