Copyright (c) 2000, 2011 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
/
package org.eclipse.jdt.internal.codeassist;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.OperationCanceledException;
The selection engine is intended to infer the nature of a selected name in some
source code. This name can be qualified.
Selection is resolving context using a name environment (no need to search), assuming
the source where selection occurred is correct and will not perform any completion
attempt. If this was the desired behavior, a call to the CompletionEngine should be
performed instead.
if (enclosingTypeNames != null && enclosingTypeNames.length > 0) return;
char[] fullyQualifiedTypeName = CharOperation.concat(packageName, simpleTypeName, '.');
if (CharOperation.equals(importName[0], simpleTypeName)) {
if(CharOperation.equals(importName[1], fullyQualifiedTypeName)) {
super.acceptType(modifiers, packageName, simpleTypeName, enclosingTypeNames, path, access);
char[] importFlatName = CharOperation.concatWith(importName, '.');
if (CharOperation.equals(importFlatName, packageName)) {
super.acceptType(modifiers, packageName, simpleTypeName, enclosingTypeNames, path, access);
for (int i = 0; i < size; i++) {
acceptedType.packageName,
acceptedType.simpleTypeName,
for (int i = 0; i < length; i++) {
importReference.tokens[importReference.tokens.length - 1],
CharOperation.concatWith(importReference.tokens, '.')
public static boolean DEBUG = false;
public static boolean PERF = false;
The SelectionEngine is responsible for computing the selected object.
It requires a searchable name environment, which supports some
specific search APIs, and a requestor to feed back the results to a UI.
- Parameters:
nameEnvironment
org.eclipse.jdt.internal.core.SearchableEnvironment
used to resolve type/package references and search for types/packages
based on partial names.requestor
org.eclipse.jdt.internal.codeassist.ISelectionRequestor
since the engine might produce answers of various forms, the engine
is associated with a requestor able to accept all possible completions.settings
java.util.Map
set of options used to configure the code assist engine.
int problemStartPosition,
public void acceptType(char[] packageName, char[] simpleTypeName, char[][] enclosingTypeNames, int modifiers, AccessRestriction accessRestriction) {
char[] typeName = enclosingTypeNames == null ?
CharOperation.concatWith(enclosingTypeNames, '.'),
char[] flatEnclosingTypeNames =
enclosingTypeNames == null || enclosingTypeNames.length == 0 ?
CharOperation.concatWith(enclosingTypeNames, '.');
if(mustQualifyType(packageName, simpleTypeName, flatEnclosingTypeNames, modifiers)) {
char[][] acceptedAnnotation = new char[2][];
acceptedAnnotation[0] = packageName;
acceptedAnnotation[1] = typeName;
int newLength = (length + 1)* 2;
char[][] acceptedEnum = new char[2][];
acceptedEnum[0] = packageName;
acceptedEnum[1] = typeName;
int newLength = (length + 1)* 2;
char[][] acceptedInterface= new char[2][];
acceptedInterface[0] = packageName;
acceptedInterface[1] = typeName;
int newLength = (length + 1)* 2;
char[][] acceptedClass = new char[2][];
acceptedClass[0] = packageName;
acceptedClass[1] = typeName;
int newLength = (length + 1)* 2;
One result of the search consists of a new package.
- Parameters:
packageName
char[]
NOTE - All package names are presented in their readable form:
Package names are in the form "a.b.c".
The default package is represented by an empty array.
int lastIdentifierStart = -1;
int lastIdentifierEnd = -1;
char[] lastIdentifier = null;
if(selectionStart > selectionEnd){
int end = source.length - 1;
int currentPosition = selectionStart - 1;
int nextCharacterPosition = selectionStart;
char currentCharacter = ' ';
lineLoop: while(currentPosition > 0){
if(source[currentPosition] == '\\' && source[currentPosition+1] == 'u') {
int pos = currentPosition + 2;
int c1 = 0, c2 = 0, c3 = 0, c4 = 0;
while (source[pos] == 'u') {
int endOfUnicode = pos + 3;
if (end < endOfUnicode) {
if (endOfUnicode < source.length) {
currentCharacter = (char) (((c1 * 16 + c2) * 16 + c3) * 16 + c4);
nextCharacterPosition = pos;
currentCharacter = source[currentPosition];
nextCharacterPosition = currentPosition+1;
switch(currentCharacter) {
scanner.resetTo(nextCharacterPosition, end);
if (scanner.startPosition <= selectionStart && selectionStart <= scanner.currentPosition) {
if (scanner.currentPosition == scanner.eofPosition) {
int temp = scanner.eofPosition;
scanner.eofPosition = scanner.source.length;
scanner.eofPosition = temp;
lastIdentifierStart = scanner.startPosition;
lastIdentifierEnd = scanner.currentPosition - 1;
scanner.resetTo(selectionStart, selectionEnd);
boolean expectingIdentifier = true;
if (!expectingIdentifier)
lastIdentifierStart = scanner.startPosition;
lastIdentifierEnd = scanner.currentPosition - 1;
if(lastIdentifierEnd > selectionEnd) {
lastIdentifierEnd = selectionEnd;
lastIdentifier = CharOperation.subarray(lastIdentifier, 0,lastIdentifierEnd - lastIdentifierStart + 1);
expectingIdentifier = false;
expectingIdentifier = true;
if(scanner.startPosition != scanner.initialPosition)
if (lastIdentifierStart > 0) {
char[] typeRef = new char[length];
int length = buffer.length() - 1;
char[] typeRef = new char[length];
IProgressMonitor progressMonitor = new IProgressMonitor() {
public void worked(int work) {
} catch (OperationCanceledException e) {
Ask the engine to compute the selection at the specified position
of the given compilation unit.
- Parameters:
sourceUnit
org.eclipse.jdt.internal.compiler.env.ICompilationUnit
the source of the current compilation unit.selectionSourceStart
intselectionSourceEnd
int
a range in the source where the selection is.
int selectionSourceStart,
int selectionSourceEnd) {
if (!checkSelection(source, selectionSourceStart, selectionSourceEnd)) {
if (parsedUnit != null) {
for (int i = 0, length = imports.length; i < length; i++) {
if ((this.unitScope = parsedUnit.scope) != null) {
int tokenCount = tokens.length;
char[] lastToken = tokens[tokenCount - 1];
char[][] qualifierTokens = CharOperation.subarray(tokens, 0, tokenCount - 1);
if(qualifierTokens != null && qualifierTokens.length > 0) {
if ((this.unitScope = parsedUnit.scope) != null) {
if (parsedUnit.types != null)
selectFrom(e.binding, parsedUnit, e.isDeclaration);
int fieldLength = lastToken.length;
next : for (int j = 0; j < memberTypes.length; j++) {
if (fieldLength > memberType.sourceName.length)
if (staticOnly && !memberType.isStatic())
if (!CharOperation.equals(lastToken, memberType.sourceName, true))
int fieldLength = lastToken.length;
next : for (int j = 0; j < fields.length; j++) {
if (fieldLength > field.name.length)
if (!CharOperation.equals(lastToken, field.name, true))
int methodLength = lastToken.length;
next : for (int j = 0; j < methods.length; j++) {
if (methodLength > method.selector.length)
if (!CharOperation.equals(lastToken, method.selector, true))
Binding enclosingElement = typeVariableBinding.declaringElement;
: enclosingMethod.selector,
if (typeBinding == null) return;