Copyright (c) 2017 IBM Corporation and others. This program and the accompanying materials are made available under the terms of the Eclipse Public License 2.0 which accompanies this distribution, and is available at https://www.eclipse.org/legal/epl-2.0/ SPDX-License-Identifier: EPL-2.0 Contributors: IBM Corporation - initial API and implementation
/******************************************************************************* * Copyright (c) 2017 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 * which accompanies this distribution, and is available at * https://www.eclipse.org/legal/epl-2.0/ * * SPDX-License-Identifier: EPL-2.0 * * Contributors: * IBM Corporation - initial API and implementation *******************************************************************************/
package org.eclipse.jdt.internal.core.search.matching; import java.io.IOException; import org.eclipse.jdt.core.compiler.CharOperation; import org.eclipse.jdt.core.search.IJavaSearchConstants; import org.eclipse.jdt.core.search.SearchPattern; import org.eclipse.jdt.internal.core.index.EntryResult; import org.eclipse.jdt.internal.core.index.Index; public class ModulePattern extends JavaSearchPattern { boolean findDeclarations = true; /* package visible */ boolean findReferences = true; /* package visible */ char[] name; /* package visible */ protected static char[][] REF_CATEGORIES = { MODULE_REF }; protected static char[][] REF_AND_DECL_CATEGORIES = { MODULE_REF, MODULE_DECL }; protected static char[][] DECL_CATEGORIES = { MODULE_DECL }; private static char[] regexPrefix = {'/','r',' '}; public static char[] createIndexKey(char[] name) { return name; // until a need arises, let the name itself be the index key. } protected ModulePattern(int matchRule) { super(MODULE_PATTERN, matchRule); } public ModulePattern(char[] name, int limitTo, int matchRule) { this(ModulePattern.trapDoorRegexMatchRule(name, matchRule)); this.name = trapDoorRegexExtractModuleName(name); switch (limitTo & 0xF) { case IJavaSearchConstants.DECLARATIONS : this.findReferences = false; break; case IJavaSearchConstants.REFERENCES : this.findDeclarations = false; break; case IJavaSearchConstants.ALL_OCCURRENCES : if ((getMatchRule() & SearchPattern.R_REGEXP_MATCH) != 0) this.findReferences = false; //regex implemented only for module declarations. break; } this.mustResolve = mustResolve(); } /* * Trap door method for implicitly triggering a regex search. * if the module name starts with regex: (case insensitive), * the rest of the characters are taken as a regular expression * for the module name. */ private static char[] trapDoorRegexExtractModuleName(char[] name2) { int index = CharOperation.indexOf(regexPrefix, name2, false); return index >= 0 ? CharOperation.subarray(name2, index + regexPrefix.length, name2.length) : name2; } /* * Sets the match rule to regular expression search as well. */ private static int trapDoorRegexMatchRule(char[] name2, int matchRule) { return CharOperation.indexOf(regexPrefix, name2, false) == 0 ? SearchPattern.R_REGEXP_MATCH : matchRule; } @Override public void decodeIndexKey(char[] key) { this.name = key; } @Override public SearchPattern getBlankPattern() { return new ModulePattern(R_EXACT_MATCH); } @Override public char[][] getIndexCategories() { if (this.findReferences) return this.findDeclarations ? REF_AND_DECL_CATEGORIES : REF_CATEGORIES; if (this.findDeclarations) return DECL_CATEGORIES; return CharOperation.NO_CHAR_CHAR; } @Override public boolean matchesDecodedKey(SearchPattern decodedPattern) { return matchesName(this.name, ((ModulePattern) decodedPattern).name); } @Override public EntryResult[] queryIn(Index index) throws IOException { char[] key = this.name; // can be null int matchRule = getMatchRule(); switch(getMatchMode()) { case R_EXACT_MATCH : if (this.name != null) { key = createIndexKey(this.name); } else { // do a prefix query with the selector matchRule &= ~R_EXACT_MATCH; matchRule |= R_PREFIX_MATCH; } break; case R_PREFIX_MATCH : // do a prefix query with the selector break; case R_PATTERN_MATCH : if (this.name != null) { key = createIndexKey(this.name); } // else do a pattern query with just the selector break; case R_REGEXP_MATCH : // nothing to do here for the regex match break; case R_CAMELCASE_MATCH: case R_CAMELCASE_SAME_PART_COUNT_MATCH: // do a prefix query with the selector break; } return index.query(getIndexCategories(), key, matchRule); // match rule is irrelevant when the key is null } protected boolean mustResolve() { return true; } @Override protected StringBuffer print(StringBuffer output) { if (this.findDeclarations) { output.append(this.findReferences ? "ModuleCombinedPattern: " //$NON-NLS-1$ : "ModuleDeclarationPattern: "); //$NON-NLS-1$ } else { output.append("ModuleReferencePattern: "); //$NON-NLS-1$ } output.append("module "); //$NON-NLS-1$ output.append(this.name); return super.print(output); } }