package org.eclipse.dltk.tcl.core; import java.util.HashMap; import java.util.List; import java.util.Map; import org.eclipse.dltk.ast.ASTNode; import org.eclipse.dltk.ast.declarations.MethodDeclaration; import org.eclipse.dltk.ast.declarations.ModuleDeclaration; import org.eclipse.dltk.ast.declarations.TypeDeclaration; import org.eclipse.dltk.core.search.matching.MatchLocator; import org.eclipse.dltk.core.search.matching.MatchLocatorParser; import org.eclipse.dltk.core.search.matching.PatternLocator; import org.eclipse.dltk.core.search.matching.PossibleMatch; public abstract class BasicTclMatchLocatorParser extends MatchLocatorParser { final protected static String[] kw = TclKeywordsManager.getKeywords(); protected static Map kwMap = new HashMap(); static { for (int q = 0; q < kw.length; ++q) { kwMap.put(kw[q], Boolean.TRUE); } } public BasicTclMatchLocatorParser(MatchLocator locator) { super(locator); } public ModuleDeclaration parse(PossibleMatch possibleMatch) { ModuleDeclaration module = super.parse(possibleMatch); module.rebuild(); module.rebuildMethods(); return module; } public void parseBodies(ModuleDeclaration unit) { TypeDeclaration[] types = unit.getTypes(); if (types != null) { for (int i = 0; i < types.length; i++) { TypeDeclaration type = types[i]; this.getPatternLocator().match(this.processType(type), this.getNodeSet()); this.parseBodies(type); } } MethodDeclaration[] methods = unit.getFunctions(); if (methods != null) { PatternLocator locator = this.getPatternLocator(); for (int i = 0; i < methods.length; i++) { MethodDeclaration method = methods[i]; locator.match(this.processMethod(method), this.getNodeSet()); this.parseBodies(method); } } ASTNode[] nodes = unit.getNonTypeOrMethodNode(); int length = nodes.length; for (int i = 0; i < length; i++) { this.processStatement(nodes[i]); } } public MethodDeclaration processMethod(final MethodDeclaration m) { String name = m.getName(); MethodDeclaration method = new MethodDeclaration(m.sourceStart(), m .sourceEnd()) { public boolean equals(Object obj) { if (obj == this) return true; if (obj instanceof ASTNode) { ASTNode s = (ASTNode) obj; if (s.sourceEnd() < 0 || s.sourceStart() < 0) { return false; } return sourceStart() == s.sourceStart() && sourceEnd() == s.sourceEnd(); } return false; } public int hashCode() { return this.sourceEnd() * 1001 + this.sourceEnd(); } }; method.setName(name); method.setNameStart(m.getNameStart()); method.setNameEnd(m.getNameEnd()); method.setModifiers(m.getModifiers()); if (name.startsWith("::")) { name = name.substring(2); } name = getRealMethodName(method); method.setDeclaringTypeName(m.getDeclaringTypeName()); method.setName(name); return method; } public String getRealMethodName(MethodDeclaration method) { String name = method.getName(); if (name.indexOf("::") != -1) { int pos = name.lastIndexOf("::"); name = name.substring(pos + 2); } return name; } public TypeDeclaration processType(final TypeDeclaration t) { String name = t.getName(); TypeDeclaration type = new TypeDeclaration(name, t.getNameStart(), t .getNameEnd(), t.sourceStart(), t.sourceEnd()) { public boolean equals(Object obj) { if (obj == this) return true; if (obj instanceof ASTNode) { ASTNode s = (ASTNode) obj; if (s.sourceEnd() < 0 || s.sourceStart() < 0) { return false; } return sourceStart() == s.sourceStart() && sourceEnd() == s.sourceEnd(); } return false; } public int hashCode() { return this.sourceEnd() * 1001 + this.sourceEnd(); } }; if (name.startsWith("::")) { name = name.substring(2); } if (name.endsWith("::")) { name = name.substring(0, name.length() - 2); } type.setName(name); type.setEnclosingTypeName(t.getEnclosingTypeName()); type.setModifier(t.getModifiers()); return type; } protected void parseBodies(TypeDeclaration type) { PatternLocator locator = this.getPatternLocator(); MethodDeclaration[] methods = type.getMethods(); if (methods != null) { for (int i = 0; i < methods.length; i++) { MethodDeclaration method = methods[i]; locator.match(this.processMethod(method), this.getNodeSet()); this.parseBodies(method); } } TypeDeclaration[] memberTypes = type.getTypes(); if (memberTypes != null) { for (int i = 0; i < memberTypes.length; i++) { TypeDeclaration memberType = memberTypes[i]; locator.match(this.processType(memberType), this.getNodeSet()); this.parseBodies(memberType); } } ASTNode[] nodes = type.getNonTypeOrMethodNode(); int length = nodes.length; for (int i = 0; i < length; i++) { this.processStatement(nodes[i]); } } protected void parseBodies(MethodDeclaration method) { List nodes = method.getStatements(); int length = nodes.size(); for (int i = 0; i < length; i++) { ASTNode node = (ASTNode) nodes.get(i); this.processStatement(node); } } protected abstract void processStatement(ASTNode node); }