/******************************************************************************* * Copyright (c) 2005, 2012 eBay Inc. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * *******************************************************************************/ package org.eclipse.vjet.eclipse.core.search; import java.util.Iterator; import java.util.List; import org.eclipse.vjet.dsf.jst.BaseJstNode; import org.eclipse.vjet.dsf.jst.IJstGlobalVar; import org.eclipse.vjet.dsf.jst.IJstMethod; import org.eclipse.vjet.dsf.jst.IJstNode; import org.eclipse.vjet.dsf.jst.IJstType; import org.eclipse.vjet.dsf.jst.JstSource; import org.eclipse.vjet.dsf.jst.declaration.JstMethod; import org.eclipse.vjet.dsf.jst.declaration.JstName; import org.eclipse.vjet.dsf.jstojava.translator.JstUtil; import org.eclipse.vjet.dsf.ts.method.MethodName; import org.eclipse.vjet.dsf.ts.type.TypeName; import org.eclipse.vjet.eclipse.codeassist.CodeassistUtils; import org.eclipse.vjet.eclipse.core.IVjoSourceModule; import org.eclipse.vjet.eclipse.core.VjetPlugin; import org.eclipse.vjet.vjo.tool.typespace.TypeSpaceMgr; import org.eclipse.dltk.mod.core.Flags; import org.eclipse.dltk.mod.core.IMethod; import org.eclipse.dltk.mod.core.IModelElement; import org.eclipse.dltk.mod.core.ISourceRange; import org.eclipse.dltk.mod.core.IType; import org.eclipse.dltk.mod.core.ModelException; import org.eclipse.dltk.mod.core.search.SearchPattern; import org.eclipse.dltk.mod.internal.core.JSSourceMethod; import org.eclipse.dltk.mod.internal.core.NativeVjoSourceModule; import org.eclipse.dltk.mod.internal.core.search.matching.MethodPattern; /** * Search declaration and references for method. * * * */ public class VjoMethodSearcher extends AbstractVjoElementSearcher { private static final String ENCLOSING_TYPE_SEPARATOR = "."; public Class<? extends SearchPattern> getSearchPatternClass() { return MethodPattern.class; } @Override protected void searchDeclarations(SearchQueryParameters params, List<VjoMatch> result) { JSSourceMethod method = (JSSourceMethod) params.getElement(); IVjoSourceModule module = (IVjoSourceModule) method.getSourceModule(); TypeName typeName = module.getTypeName(); IType type = CodeassistUtils.findType(module, typeName.typeName()); if (isInScope(type)) { try { ISourceRange nameRange = method.getNameRange(); VjoMatch match = VjoMatchFactory.createMethodMatch(type, nameRange.getOffset(), nameRange.getLength()); // Add by Oliver.2009-06-25. try { match.setIsPublic(Flags.isPublic(method.getFlags())); match.setIsStatic(Flags.isStatic(method.getFlags())); } catch (ModelException e) { } result.add(match); } catch (ModelException e) { // VjetPlugin.getDefault().getLog().log( // new Status(IStatus.ERROR, VjetPlugin.PLUGIN_ID, // IStatus.ERROR, "Wrong name range", e)); } } } @Override protected void searchReferences(SearchQueryParameters params, List<VjoMatch> result) { IMethod method = (IMethod) params.getElement(); if (method.getSourceModule() instanceof NativeVjoSourceModule) this.processNativeMethodReference(method, result); else this.processSourceMethodReference(method, result); } // process source method reference: including source method in inner type private void processSourceMethodReference(IMethod method, List<VjoMatch> result) { IVjoSourceModule module = (IVjoSourceModule) method.getSourceModule(); IJstType jstType = module.getJstType(); // IType type = CodeassistUtils.findType(jstType); // String dltkTypeName = ((IType) method.getParent()) // .getFullyQualifiedName(ENCLOSING_TYPE_SEPARATOR); int offset; IJstMethod jstMethod = null; try { offset = method.getNameRange().getOffset(); BaseJstNode node = JstUtil.getLeafNode(jstType, offset, offset); if(node!=null && node instanceof JstName){ jstMethod = (IJstMethod)node.getParentNode(); } } catch (ModelException e) { // TODO Auto-generated catch block e.printStackTrace(); } // this.getJstMethod(jstType, dltkTypeName, method // .getElementName(), true); if (jstMethod == null) return; // work out PropertyName and find referenced nodes from TypeSpaceMgr String grouName = jstMethod.getOwnerType().getPackage().getGroupName(); String typeName = jstMethod.getOwnerType().getName(); // TODO how do we handle nested functions here? MethodName methodName = new MethodName( new TypeName(grouName, typeName), method.getElementName()); // find reference nodes List<IJstNode> list = mgr.getMethodDependents(methodName); for (Iterator iterator = list.iterator(); iterator.hasNext();) { IJstNode jstNode = (IJstNode) iterator.next(); this.createMatch(jstNode, method, result); } } // process native method reference: because currently, native type name does // not match IJstType.getAlias private void processNativeMethodReference(IMethod method, List<VjoMatch> result) { NativeVjoSourceModule nativeVjoSourceModule = (NativeVjoSourceModule) method .getSourceModule(); String groupName = nativeVjoSourceModule.getTypeName().groupName(); String typeName = nativeVjoSourceModule.getJstType().getName(); IModelElement parent = method.getParent(); // if (parent instanceof IType) { // typeName = ((IType) parent) // .getTypeQualifiedName(ENCLOSING_TYPE_SEPARATOR); // } MethodName methodNameTest = new MethodName(new TypeName(groupName, typeName), method.getElementName()); List<IJstNode> list = mgr.getMethodDependents(methodNameTest); for (Iterator iterator = list.iterator(); iterator.hasNext();) { IJstNode jstNode = (IJstNode) iterator.next(); this.createMatch(jstNode, method, result); } } // currently, not support anoymous inner type private IJstMethod getJstMethod(IJstType type, String typeName, String methodName, boolean alias) { if(type==null){ return null; } if ((alias) || (!alias && type.getName().equals(typeName))) { IJstMethod jstMethod = type.getMethod(methodName); if (jstMethod == null && "constructs".equals(methodName)) jstMethod = type.getConstructor(); if (jstMethod == null) { IJstGlobalVar gvar = type.getGlobalVar(methodName); if(gvar!=null){ jstMethod = gvar.getFunction(); } } return jstMethod; } else { // iterate inner types... for (Iterator iterator = type.getEmbededTypes().iterator(); iterator .hasNext();) { IJstType innerType = (IJstType) iterator.next(); IJstMethod jstMethod = this.getJstMethod(innerType, typeName, methodName, alias); if (jstMethod != null) return jstMethod; } } return null; } private void createMatch(IJstNode jstNode, IMethod method, List<VjoMatch> result) { //if (!isValidNode(jstNode)) //return; IJstType ownerType = jstNode.getOwnerType(); IType dltkType = CodeassistUtils.findType(ownerType); if (dltkType == null){ VjetPlugin.error("Could not find DLTKType for JstType: " + ownerType.getName()); return; } //Check if the file is visible in the result project's build path // IType declareType = CodeassistUtils.findType((ScriptProject)dltkType.getScriptProject(), method.getDeclaringType().getFullyQualifiedName(".")); // if (declareType == null) { // return; // } JstSource jstSource = jstNode.getSource(); int length = jstSource.getEndOffSet() - jstSource.getStartOffSet() + 1; VjoMatch match = VjoMatchFactory.createTypeMatch(dltkType, jstSource .getStartOffSet(), length); result.add(match); } /** * filer the temp method created by back-end. * * @param node * @return */ private boolean isValidNode(IJstNode node) { IJstMethod jstMethod = CodeassistUtils.findDeclaringMethod(node); if (jstMethod == null) { return true; } if (jstMethod.isConstructor()) { return jstMethod.getOwnerType().getConstructor() != null; } IJstMethod validJstMethod = jstMethod.getOwnerType().getMethod( jstMethod.getName().getName()); // if (jstMethod.equals(validJstMethod)) // if (jstMethod == validJstMethod) // return false; return validJstMethod != null; } // add by patrick /* * (non-Javadoc) * * @see * org.eclipse.vjet.eclipse.core.search.AbstractVjoElementSearcher#findOccurrence * (org.eclipse.vjet.dsf.jst.IJstNode, org.eclipse.vjet.dsf.jst.IJstNode) */ public List<VjoMatch> findOccurrence(IJstNode searchedJstNode, IJstNode searchedTree) { if(searchedJstNode.getParentNode() instanceof IJstMethod){ searchedJstNode = (IJstMethod)searchedJstNode.getParentNode(); } VjoMehtodOccurrenceVisitor visitor = new VjoMehtodOccurrenceVisitor( (IJstMethod) searchedJstNode); searchedTree.accept(visitor); return visitor.getMatches(); } // end add }