/******************************************************************************* * Copyright (c) 2009 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 * * Contributors: * IBM Corporation - initial API and implementation * Zend Technologies *******************************************************************************/ package org2.eclipse.php.internal.core.search; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import org.eclipse.core.resources.IMarker; import org.eclipse.core.resources.IResource; import org.eclipse.core.runtime.CoreException; import org2.eclipse.dltk.compiler.problem.DefaultProblem; import org2.eclipse.php.internal.core.CoreMessages; import org2.eclipse.php.internal.core.ast.nodes.ASTNode; import org2.eclipse.php.internal.core.ast.nodes.Identifier; import org2.eclipse.php.internal.core.ast.nodes.NamespaceDeclaration; import org2.eclipse.php.internal.core.ast.nodes.Program; import org2.eclipse.php.internal.core.ast.nodes.UseStatement; import org2.eclipse.php.internal.core.ast.nodes.UseStatementPart; import org2.eclipse.php.internal.core.ast.visitor.AbstractVisitor; import org2.eclipse.php.internal.core.corext.NodeFinder; import com.aptana.core.resources.IUniformResource; import com.aptana.core.resources.MarkerUtils; /** * A base class for all the occurrence finders. * * @author shalom */ public abstract class AbstractOccurrencesFinder extends AbstractVisitor implements IOccurrencesFinder { public final static char NAMESPACE_SEPARATOR = '\\'; protected static final String BASE_DESCRIPTION = CoreMessages .getString("AbstractOccurrencesFinder.0"); //$NON-NLS-1$ protected static final String BASE_WRITE_DESCRIPTION = CoreMessages .getString("AbstractOccurrencesFinder.1"); //$NON-NLS-1$ protected static final String BRACKETS = "()"; //$NON-NLS-1$ protected List<OccurrenceLocation> fResult; protected String fDescription; protected Program fASTRoot; protected ProblemDesc[] fProblems; protected NamespaceDeclaration fCurrentNamespace; protected Map<String, UseStatementPart> fLastUseParts = new HashMap<String, UseStatementPart>(); static class ProblemDesc { int kind; int offset; int end; int severity; public ProblemDesc(int kind, int offset, int end, int severity) { this.kind = kind; this.offset = offset; this.end = end; this.severity = severity; } public boolean isError() { // return (this.severity & ProblemSeverities.Error) != 0; return (this.severity == 1); } } /* * (non-Javadoc) * * @see * org2.eclipse.php.internal.ui.search.IOccurrencesFinder#initialize(org. * eclipse.php.internal.core.ast.nodes.Program, int, int) */ public String initialize(Program root, int offset, int length) { return initialize(root, NodeFinder.perform(root, offset, length)); } /* * (non-Javadoc) * * @see * org2.eclipse.php.internal.ui.search.IOccurrencesFinder#getOccurrences() */ public OccurrenceLocation[] getOccurrences() { fResult = new ArrayList<OccurrenceLocation>(); findOccurrences(); if (fResult.isEmpty()) return null; return fResult.toArray(new OccurrenceLocation[fResult.size()]); } /** * Returns all problems in this program * * @param node * @return */ public static ProblemDesc[] getProblems(Program node) { try { if (node.getSourceModule() == null) { return null; } Object resource = node.getSourceModule().getResource(); if (resource != null) { IMarker[] markers = null; if (resource instanceof IResource) { markers = ((IResource) resource).findMarkers(DefaultProblem.MARKER_TYPE_PROBLEM, true, IResource.DEPTH_ONE); } else if (resource instanceof IUniformResource) { markers = MarkerUtils.findMarkers((IUniformResource) resource, DefaultProblem.MARKER_TYPE_PROBLEM, true); } if (markers == null) { return null; } ProblemDesc[] problems = new ProblemDesc[markers.length]; for (int i = 0; i < markers.length; ++i) { problems[i] = new ProblemDesc(markers[i].getAttribute("id", //$NON-NLS-1$ 0), markers[i].getAttribute(IMarker.CHAR_START, 0), markers[i].getAttribute( IMarker.CHAR_END, 0), markers[i].getAttribute(IMarker.SEVERITY, 0)); } return problems; } } catch (CoreException e) { } return null; } /** * Whether the specified source range contains error * * @param offset * @param end * @return */ protected boolean hasProblems(int offset, int end) { if (fProblems != null) { // Check that current location doesn't contain errors for (ProblemDesc problemDesc : fProblems) { if (problemDesc.offset <= offset && problemDesc.end >= end) { return true; } } } return false; } /** * Adds occurrence to results list in case there's no error in this position * * @param location * Occurrence location */ protected void addOccurrence(OccurrenceLocation location) { if (!hasProblems(location.getOffset(), location.getOffset() + location.getLength())) { fResult.add(location); } } /** * Find and add all the occurrences. Extending finders must implement this * method to fill the results list. Note that this method should not be * called directly. It is being called by the {@link #getOccurrences()}. * * @see #getOccurrences() */ protected abstract void findOccurrences(); /** * Returns the type of this occurrence. * * @param node * The {@link ASTNode} to check. * @return The occurrence type (one of {@link IOccurrencesFinder} type * constants) * @see IOccurrencesFinder */ protected abstract int getOccurrenceType(ASTNode node); /* * (non-Javadoc) * * @see org2.eclipse.php.internal.ui.search.IOccurrencesFinder#getASTRoot() */ public Program getASTRoot() { return fASTRoot; } /* * (non-Javadoc) * * @see org2.eclipse.php.internal.ui.search.IOccurrencesFinder#getJobLabel() */ public String getJobLabel() { return "OccurrencesFinder_job_label"; //$NON-NLS-1$ } /* * (non-Javadoc) * * @see * org2.eclipse.php.internal.ui.search.IOccurrencesFinder#getSearchKind() */ public int getSearchKind() { return IOccurrencesFinder.K_OCCURRENCE; } /* * (non-Javadoc) * * @see org2.eclipse.php.internal.ui.search.IOccurrencesFinder# * getUnformattedPluralLabel() */ public String getUnformattedPluralLabel() { return "OccurrencesFinder_label_plural"; //$NON-NLS-1$ } /* * (non-Javadoc) * @see org2.eclipse.php.internal.ui.search.IOccurrencesFinder# getUnformattedSingularLabel() */ public String getUnformattedSingularLabel() { return "OccurrencesFinder_label_singular"; //$NON-NLS-1$ } public boolean visit(NamespaceDeclaration namespaceDeclaration) { fCurrentNamespace = namespaceDeclaration; fLastUseParts.clear(); return true; } public void endVisit(NamespaceDeclaration namespaceDeclaration) { fCurrentNamespace = null; fLastUseParts.clear(); } public boolean visit(UseStatement useStatement) { List<UseStatementPart> useParts = useStatement.parts(); for (UseStatementPart part : useParts) { String name = null; if (part.getAlias() != null) { name = part.getAlias().getName(); } else { name = part.getName().getName(); int index = name .lastIndexOf(NAMESPACE_SEPARATOR); if (index >= 0) { name = name.substring(index + 1); } } fLastUseParts.put(name, part); } return true; } public static String getFullName(Identifier identifier, Map<String, UseStatementPart> lastUseParts, NamespaceDeclaration currentNamespace) { return getFullName(identifier.getName(), lastUseParts, currentNamespace); } public static String getFullName(String fullName, Map<String, UseStatementPart> lastUseParts, NamespaceDeclaration currentNamespace) { if (fullName.charAt(0) != NAMESPACE_SEPARATOR) { int index = fullName .lastIndexOf(NAMESPACE_SEPARATOR); if (index >= 0) { String namespace = fullName.substring(0, index); if (lastUseParts.containsKey(namespace)) { fullName = new StringBuilder(lastUseParts.get(namespace) .getName().getName()).append( NAMESPACE_SEPARATOR).append( fullName.substring(index + 1)).toString(); } } else if (lastUseParts.containsKey(fullName)) { fullName = new StringBuilder(lastUseParts.get(fullName) .getName().getName()).toString(); } else { if (currentNamespace != null && currentNamespace.getName() != null) { fullName = new StringBuilder(currentNamespace.getName() .getName()).append( NAMESPACE_SEPARATOR).append( fullName).toString(); } } } if (fullName.charAt(0) == NAMESPACE_SEPARATOR) { fullName = fullName.substring(1); } return fullName; } }