blob: 2a12455d5822a7d5498dcb4c132b07837ae8067f [file] [log] [blame]
/*******************************************************************************
* 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);
}
}