package org.fandev.runner; import com.intellij.execution.filters.Filter; import com.intellij.execution.filters.OpenFileHyperlinkInfo; import com.intellij.openapi.fileEditor.OpenFileDescriptor; import com.intellij.openapi.project.Project; import org.fandev.index.FanIndex; import org.fandev.lang.fan.psi.FanFile; import org.fandev.lang.fan.psi.api.statements.typeDefs.FanTypeDefinition; import org.fandev.lang.fan.psi.api.statements.typeDefs.members.FanMethod; import java.util.regex.Pattern; import java.util.regex.Matcher; /** * Date: Sep 23, 2009 * Time: 11:54:45 PM * * @author Dror Bereznitsky */ public class FanTypeFilter implements Filter { private Project project; private FanIndex index; // pattern for matching Fan identifiers: pod::type.method private final Pattern identifier = Pattern.compile("^.*(\\b[a-zA-Z0-9_]+::[a-zA-Z0-9_\\.]+).*\n"); // pattern for mathcing line number inside a Fan file, for example: (HelloWorld.fan:9) private final Pattern lineInFile = Pattern.compile("^.*(\\(.*\\.fan:)(\\d+)(\\)).*\n"); public FanTypeFilter(final Project project) { this.project = project; this.index = project.getComponent(FanIndex.class); } public Result applyFilter(final String line, final int entireLength) { Matcher m = identifier.matcher(line); if (m.matches()) { final String id = m.group(1); final int start = line.indexOf(id); String typeName = id.substring(id.indexOf("::") + 2); String methodName = null; final int dotIdx = typeName.indexOf("."); if (dotIdx > -1) { methodName = typeName.substring(dotIdx + 1); typeName = typeName.substring(0, dotIdx); } final FanFile file = index.getFanFileByTypeName(typeName); if (file != null) { int offset; m = lineInFile.matcher(line); if (m.matches()) { // We have the line number in the stack trace offset = Integer.valueOf(m.group(2)).intValue() - 1; return new Result( entireLength - line.length() + start, entireLength - line.length() + start + id.length(), new OpenFileHyperlinkInfo(new OpenFileDescriptor(project, file.getVirtualFile(), offset, 0))); } else { // No line number, get the type or method offset inside the file final FanTypeDefinition typeDef = file.getTypeByName(typeName); offset = typeDef.getTextOffset(); if (methodName != null) { final FanMethod fanMethod = typeDef.getMethodByName(methodName); if (fanMethod != null) { offset = fanMethod.getTextOffset(); } } return new Result( entireLength - line.length() + start, entireLength - line.length() + start + id.length(), new OpenFileHyperlinkInfo(new OpenFileDescriptor(project, file.getVirtualFile(), offset))); } } } return null; } }