/******************************************************************************* * Copyright (c) 2005, 2017 IBM Corporation and others. * 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.dltk.tcl.internal.core; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.dltk.ast.references.SimpleReference; import org.eclipse.dltk.compiler.SourceElementRequestorAdaptor; import org.eclipse.dltk.compiler.env.MethodSourceCode; import org.eclipse.dltk.core.DLTKCore; import org.eclipse.dltk.core.DLTKLanguageManager; import org.eclipse.dltk.core.ICalleeProcessor; import org.eclipse.dltk.core.IMethod; import org.eclipse.dltk.core.IModelElement; import org.eclipse.dltk.core.ISourceElementParser; import org.eclipse.dltk.core.ISourceModule; import org.eclipse.dltk.core.ModelException; import org.eclipse.dltk.core.search.IDLTKSearchScope; import org.eclipse.dltk.core.search.SearchEngine; import org.eclipse.dltk.core.search.SearchParticipant; import org.eclipse.dltk.core.search.SearchPattern; import org.eclipse.dltk.core.search.SearchRequestor; import org.eclipse.dltk.tcl.core.TclNature; public class TclCalleeProcessor implements ICalleeProcessor { protected static int EXACT_RULE = SearchPattern.R_EXACT_MATCH | SearchPattern.R_CASE_SENSITIVE; private Map fSearchResults = new HashMap(); private IMethod method; // private IDLTKSearchScope scope; public TclCalleeProcessor(IMethod method, IProgressMonitor monitor, IDLTKSearchScope scope) { this.method = method; // this.scope = scope; } private class CaleeSourceElementRequestor extends SourceElementRequestorAdaptor { @Override public void acceptMethodReference(String methodName, int argCount, int sourcePosition, int sourceEndPosition) { int off = 0; try { off = method.getSourceRange().getOffset(); } catch (ModelException e) { if (DLTKCore.DEBUG) { e.printStackTrace(); } } SimpleReference ref = new SimpleReference(off + sourcePosition, off + sourceEndPosition, methodName); IMethod[] methods = findMethods(methodName, argCount, off + sourcePosition); fSearchResults.put(ref, methods); } } @Override public Map doOperation() { try { if (method.getSource() != null) { CaleeSourceElementRequestor requestor = new CaleeSourceElementRequestor(); ISourceElementParser parser = DLTKLanguageManager .getSourceElementParser(TclNature.NATURE_ID); parser.setRequestor(requestor); parser.parseSourceModule(new MethodSourceCode(method)); } else { // TODO: Report error here. } return fSearchResults; } catch (ModelException e) { if (DLTKCore.DEBUG) { e.printStackTrace(); } } catch (CoreException e) { if (DLTKCore.DEBUG) { e.printStackTrace(); } } return fSearchResults; } public IMethod[] findMethods(final String methodName, int argCount, int sourcePosition) { final List<IModelElement> methods = new ArrayList<>(); ISourceModule module = this.method.getSourceModule(); try { IModelElement[] elements = module.codeSelect(sourcePosition, methodName.length()); for (int i = 0; i < elements.length; ++i) { if (elements[i] instanceof IMethod) { methods.add(elements[i]); } } } catch (ModelException e) { if (DLTKCore.DEBUG) { e.printStackTrace(); } } // final String nsName; // if( methodName.indexOf("::") != -1 ) { // String mmName = methodName; // if( mmName.startsWith("::")) { // mmName = mmName.substring(2); // } // if( mmName.indexOf("::") != -1 ) { // int posb = mmName.indexOf("::"); // nsName = mmName.substring(0, posb); // } // else { // nsName = null; // } // } // else { // nsName = null; // } // SearchRequestor requestor = new SearchRequestor() { // public void acceptSearchMatch(SearchMatch match) throws CoreException // { // Object element = match.getElement(); // if( element instanceof IMethod ) { // IMethod method = (IMethod)element; // String mn = method.getTypeQualifiedName('$', false).replaceAll("\\$", // "::"); // if( mn.equals(methodName) && !isIgnoredBySearchScope(method) ) { // methods.add(method); // } // } // else { // IType type = (IType) element; // if( !( type.getParent() instanceof ISourceModule )) { // return; // } // processTypeFunctions(type); // } // } // private void processTypeFunctions(IType type) throws ModelException { // IMethod[] tmethods = type.getMethods(); // for (int i = 0; i < tmethods.length; ++i) { // String mn = tmethods[i].getTypeQualifiedName('$', // false).replaceAll("\\$", "::"); // if( mn.equals(methodName) && !isIgnoredBySearchScope(tmethods[i]) ) { // methods.add(tmethods[i]); // } // } // IType[] types = type.getTypes(); // for( int i = 0; i < types.length; ++i ) { // processTypeFunctions(types[i]); // } // } // }; // // try { // String pattern = methodName; // if( pattern.startsWith("::")) { // pattern = pattern.substring(2); // } // if( pattern.indexOf("::")==-1) { // search(pattern, IDLTKSearchConstants.METHOD, // IDLTKSearchConstants.DECLARATIONS, scope, requestor); // } // if( nsName != null ) { // search(nsName, IDLTKSearchConstants.TYPE, // IDLTKSearchConstants.DECLARATIONS, scope, requestor); // } // } catch (CoreException e) { // // TODO Auto-generated catch block // e.printStackTrace(); // } return methods.toArray(new IMethod[methods.size()]); } protected void search(String patternString, int searchFor, int limitTo, IDLTKSearchScope scope, SearchRequestor resultCollector) throws CoreException { search(patternString, searchFor, limitTo, EXACT_RULE, scope, resultCollector); } protected void search(String patternString, int searchFor, int limitTo, int matchRule, IDLTKSearchScope scope, SearchRequestor requestor) throws CoreException { if (patternString.indexOf('*') != -1 || patternString.indexOf('?') != -1) { matchRule |= SearchPattern.R_PATTERN_MATCH; } SearchPattern pattern = SearchPattern.createPattern(patternString, searchFor, limitTo, matchRule, scope.getLanguageToolkit()); new SearchEngine().search(pattern, new SearchParticipant[] { SearchEngine.getDefaultSearchParticipant() }, scope, requestor, null); } }