Download
Getting Started
Members
Projects
Community
Marketplace
Events
Planet Eclipse
Newsletter
Videos
Participate
Report a Bug
Forums
Mailing Lists
Wiki
IRC
How to Contribute
Working Groups
Automotive
Internet of Things
LocationTech
Long-Term Support
PolarSys
Science
OpenMDM
More
Community
Marketplace
Events
Planet Eclipse
Newsletter
Videos
Participate
Report a Bug
Forums
Mailing Lists
Wiki
IRC
How to Contribute
Working Groups
Automotive
Internet of Things
LocationTech
Long-Term Support
PolarSys
Science
OpenMDM
Toggle navigation
Bugzilla – Attachment 363 Details for
Bug 9785
Problem in IType.resolveType()
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
Log In
[x]
|
Terms of Use
|
Copyright Agent
modified SelectionEngine.java from 0125 stable build
SelectionEngine.java (text/plain), 19.68 KB, created by
Scott Rich
on 2002-02-13 16:28:14 EST
(
hide
)
Description:
modified SelectionEngine.java from 0125 stable build
Filename:
MIME Type:
Creator:
Scott Rich
Created:
2002-02-13 16:28:14 EST
Size:
19.68 KB
patch
obsolete
>package org.eclipse.jdt.internal.codeassist; > >/* > * (c) Copyright IBM Corp. 2000, 2001. > * All Rights Reserved. > */ >import java.util.*; > >import org.eclipse.jdt.internal.codeassist.impl.*; >import org.eclipse.jdt.internal.codeassist.select.*; >import org.eclipse.jdt.internal.compiler.*; >import org.eclipse.jdt.internal.compiler.env.*; >import org.eclipse.jdt.internal.compiler.ast.*; >import org.eclipse.jdt.internal.compiler.lookup.*; >import org.eclipse.jdt.internal.compiler.parser.*; >import org.eclipse.jdt.internal.compiler.problem.*; >import org.eclipse.jdt.internal.compiler.util.*; >import org.eclipse.jdt.internal.compiler.impl.*; > >/** > * 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. > */ >public final class SelectionEngine extends Engine implements ISearchRequestor { > > SelectionParser parser; > ISearchableNameEnvironment nameEnvironment; > ISelectionRequestor requestor; > > CompilationUnitScope unitScope; > boolean acceptedAnswer; > > private int actualSelectionStart; > private int actualSelectionEnd; > private char[] qualifiedSelection; > private char[] selectedIdentifier; > > /** > * 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. > * > * @param environment com.ibm.codeassist.java.api.INameEnvironment > * used to resolve type/package references and search for types/packages > * based on partial names. > * > * @param requestor com.ibm.codeassist.java.api.ISelectionRequestor > * since the engine might produce answers of various forms, the engine > * is associated with a requestor able to accept all possible completions. > * > * @param options com.ibm.compiler.java.api.ConfigurableOptions > * set of options used to configure the code assist engine. > */ > public SelectionEngine( > ISearchableNameEnvironment nameEnvironment, > ISelectionRequestor requestor, > Map settings) { > this.requestor = requestor; > this.nameEnvironment = nameEnvironment; > > CompilerOptions options = new CompilerOptions(settings); > ProblemReporter problemReporter = > new ProblemReporter( > DefaultErrorHandlingPolicies.proceedWithAllProblems(), > options, > new DefaultProblemFactory(Locale.getDefault())) { > public void record(IProblem problem, CompilationResult unitResult) { > unitResult.record(problem); > SelectionEngine.this.requestor.acceptError(problem); > } > }; > this.parser = new SelectionParser(problemReporter, options.assertMode); > this.lookupEnvironment = > new LookupEnvironment(this, options, problemReporter, nameEnvironment); > } > > /** > * One result of the search consists of a new class. > * > * NOTE - All package and type names are presented in their readable form: > * Package names are in the form "a.b.c". > * Nested type names are in the qualified form "A.M". > * The default package is represented by an empty array. > */ > public void acceptClass(char[] packageName, char[] className, int modifiers) { > > if (CharOperation.equals(className, selectedIdentifier)) { > if (qualifiedSelection != null > && !CharOperation.equals( > qualifiedSelection, > CharOperation.concat(packageName, className, '.'))) { > return; > } > requestor.acceptClass( > packageName, > className, > mustQualifyType(CharOperation.splitOn('.', packageName), className)); > acceptedAnswer = true; > } > } > > /** > * One result of the search consists of a new interface. > * > * NOTE - All package and type names are presented in their readable form: > * Package names are in the form "a.b.c". > * Nested type names are in the qualified form "A.I". > * The default package is represented by an empty array. > */ > public void acceptInterface( > char[] packageName, > char[] interfaceName, > int modifiers) { > > if (CharOperation.equals(interfaceName, selectedIdentifier)) { > if (qualifiedSelection != null > && !CharOperation.equals( > qualifiedSelection, > CharOperation.concat(packageName, interfaceName, '.'))) { > return; > } > requestor.acceptInterface( > packageName, > interfaceName, > mustQualifyType(CharOperation.splitOn('.', packageName), interfaceName)); > acceptedAnswer = true; > } > } > > /** > * One result of the search consists of a new package. > * > * 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. > */ > public void acceptPackage(char[] packageName) { > } > > /** > * One result of the search consists of a new type. > * > * NOTE - All package and type names are presented in their readable form: > * Package names are in the form "a.b.c". > * Nested type names are in the qualified form "A.M". > * The default package is represented by an empty array. > */ > public void acceptType(char[] packageName, char[] typeName) { > acceptClass(packageName, typeName, 0); > } > > private boolean checkSelection( > char[] source, > int selectionStart, > int selectionEnd) { > > Scanner scanner = new Scanner(); > scanner.setSourceBuffer(source); > scanner.resetTo(selectionStart, selectionEnd); > > int lastIdentifierStart = -1; > int lastIdentifierEnd = -1; > int token, identCount = 0; > char[] lastIdentifier = null; > boolean expectingIdentifier = true; > StringBuffer entireSelection = > new StringBuffer(selectionEnd - selectionStart + 1); > do { > try { > token = scanner.getNextToken(); > } catch (InvalidInputException e) { > return false; > } > switch (token) { > case TerminalSymbols.TokenNamethis : > case TerminalSymbols.TokenNamesuper : > case TerminalSymbols.TokenNameIdentifier : > if (!expectingIdentifier) > return false; > lastIdentifier = scanner.getCurrentTokenSource(); > lastIdentifierStart = scanner.startPosition; > lastIdentifierEnd = scanner.currentPosition - 1; > if(lastIdentifierEnd > selectionEnd) { > lastIdentifierEnd = selectionEnd; > lastIdentifier = CharOperation.subarray(lastIdentifier, 0,lastIdentifierEnd - lastIdentifierStart + 1); > } > entireSelection.append(lastIdentifier); > > identCount++; > expectingIdentifier = false; > break; > case TerminalSymbols.TokenNameDOT : > if (expectingIdentifier) > return false; > entireSelection.append('.'); > expectingIdentifier = true; > break; > case TerminalSymbols.TokenNameEOF : > if (expectingIdentifier) > return false; > break; > default : > return false; > } > } while (token != TerminalSymbols.TokenNameEOF); > if (lastIdentifierStart > 0) { > actualSelectionStart = lastIdentifierStart; > actualSelectionEnd = lastIdentifierEnd; > selectedIdentifier = lastIdentifier; > if (identCount > 1) > qualifiedSelection = entireSelection.toString().toCharArray(); > return true; > } > return false; > } > > public AssistParser getParser() { > return parser; > } > > private boolean mustQualifyType( > char[][] packageName, > char[] readableTypeName) { > > // If there are no types defined into the current CU yet. > if (unitScope == null) return true; > if (CharOperation.equals(unitScope.fPackage.compoundName, packageName)) > return false; > > ImportBinding[] imports = unitScope.imports; > for (int i = 0, length = imports.length; i < length; i++) { > if (imports[i].onDemand) { > if (CharOperation.equals(imports[i].compoundName, packageName)) > return false; // how do you match p1.p2.A.* ? > } else > if (CharOperation.equals(imports[i].readableName(), readableTypeName)) { > return false; > } > } > return true; > } > > /** > * Ask the engine to compute the selection at the specified position > * of the given compilation unit. > * > * @return void > * the selection result is answered through a requestor. > * > * @param unit com.ibm.compiler.java.api.env.ICompilationUnit > * the source of the current compilation unit. > * > * @param selectionSourceStart int > * @param selectionSourceEnd int > * a range in the source where the selection is. > */ > public void select( > ICompilationUnit sourceUnit, > int selectionSourceStart, > int selectionSourceEnd) { > > char[] source = sourceUnit.getContents(); > if (!checkSelection(source, selectionSourceStart, selectionSourceEnd)) > return; > try { > acceptedAnswer = false; > CompilationResult result = new CompilationResult(sourceUnit, 1, 1); > CompilationUnitDeclaration parsedUnit = > parser.dietParse(sourceUnit, result, actualSelectionStart, actualSelectionEnd); > > if (parsedUnit != null) { > // scan the package & import statements first > if (parsedUnit.currentPackage instanceof SelectionOnPackageReference) { > char[][] tokens = > ((SelectionOnPackageReference) parsedUnit.currentPackage).tokens; > requestor.acceptPackage(CharOperation.concatWith(tokens, '.')); > return; > } > ImportReference[] imports = parsedUnit.imports; > if (imports != null) { > for (int i = 0, length = imports.length; i < length; i++) { > ImportReference importReference = imports[i]; > if (importReference instanceof SelectionOnImportReference) { > char[][] tokens = ((SelectionOnImportReference) importReference).tokens; > requestor.acceptPackage(CharOperation.concatWith(tokens, '.')); > nameEnvironment.findTypes(CharOperation.concatWith(tokens, '.'), this); > if (!acceptedAnswer) > nameEnvironment.findTypes(selectedIdentifier, this); > // try with simple type name > return; > } > } > } > if (parsedUnit.types != null) { > lookupEnvironment.buildTypeBindings(parsedUnit); > if (parsedUnit.scope != null) { > try { > lookupEnvironment.completeTypeBindings(parsedUnit, true); > parsedUnit.scope.faultInTypes(); > selectDeclaration(parsedUnit); > parseMethod(parsedUnit, selectionSourceStart); > parsedUnit.resolve(); > } catch (SelectionNodeFound e) { > if (e.binding != null) { > // if null then we found a problem in the selection node > selectFrom(e.binding); > } > } > } > } > } > // only reaches here if no selection could be derived from the parsed tree > // thus use the selected source and perform a textual type search > if (!acceptedAnswer) { > nameEnvironment.findTypes(selectedIdentifier, this); > } > } catch (IndexOutOfBoundsException e) { // work-around internal failure - 1GEMF6D > } catch (AbortCompilation e) { // ignore this exception for now since it typically means we cannot find java.lang.Object > } finally { > reset(); > } > } > > private void selectFrom(Binding binding) { > if (binding instanceof ReferenceBinding) { > ReferenceBinding typeBinding = (ReferenceBinding) binding; > if (qualifiedSelection != null > && !CharOperation.equals(qualifiedSelection, typeBinding.readableName())) { > return; > } > if (typeBinding.isInterface()) { > requestor.acceptInterface( > typeBinding.qualifiedPackageName(), > typeBinding.qualifiedSourceName(), > false); > } else if(typeBinding instanceof ProblemReferenceBinding){ > ProblemReferenceBinding problemBinding = (ProblemReferenceBinding)typeBinding; > if(problemBinding.original == null > || !(problemBinding.original instanceof ReferenceBinding)) { > return; > } > ReferenceBinding original = (ReferenceBinding) problemBinding.original; > > requestor.acceptClass( > original.qualifiedPackageName(), > original.qualifiedSourceName(), > false); > } else { > requestor.acceptClass( > typeBinding.qualifiedPackageName(), > typeBinding.qualifiedSourceName(), > false); > } > acceptedAnswer = true; > } else > if (binding instanceof MethodBinding) { > MethodBinding methodBinding = (MethodBinding) binding; > TypeBinding[] parameterTypes = methodBinding.parameters; > int length = parameterTypes.length; > char[][] parameterPackageNames = new char[length][]; > char[][] parameterTypeNames = new char[length][]; > for (int i = 0; i < length; i++) { > parameterPackageNames[i] = parameterTypes[i].qualifiedPackageName(); > parameterTypeNames[i] = parameterTypes[i].qualifiedSourceName(); > } > requestor.acceptMethod( > methodBinding.declaringClass.qualifiedPackageName(), > methodBinding.declaringClass.qualifiedSourceName(), > methodBinding.isConstructor() > ? methodBinding.declaringClass.sourceName() > : methodBinding.selector, > parameterPackageNames, > parameterTypeNames); > acceptedAnswer = true; > } else > if (binding instanceof FieldBinding) { > FieldBinding fieldBinding = (FieldBinding) binding; > if (fieldBinding.declaringClass != null) { // arraylength > requestor.acceptField( > fieldBinding.declaringClass.qualifiedPackageName(), > fieldBinding.declaringClass.qualifiedSourceName(), > fieldBinding.name); > acceptedAnswer = true; > } > } else > if (binding instanceof LocalVariableBinding) { > selectFrom(((LocalVariableBinding) binding).type); > // open on the type of the variable > } else > if (binding instanceof ArrayBinding) { > selectFrom(((ArrayBinding) binding).leafComponentType); > // open on the type of the array > } else > if (binding instanceof PackageBinding) { > PackageBinding packageBinding = (PackageBinding) binding; > requestor.acceptPackage(packageBinding.readableName()); > acceptedAnswer = true; > } > } > > /** > * Asks the engine to compute the selection of the given type > * from the source type. > * > * @return void > * the selection result is answered through a requestor. > * > * @param sourceType com.ibm.compiler.java.api.env.ISourceType > * a source form of the current type in which code assist is invoked. > * > * @param typeName char[] > * a type name which is to be resolved in the context of a compilation unit. > * NOTE: the type name is supposed to be correctly reduced (no whitespaces, no unicodes left) > */ > public void selectType(ISourceType sourceType, char[] typeName) { > try { > acceptedAnswer = false; > /* The incoming typeName is not qualified, setting qualifiedSelection > * here causes the hit on this type to be ignored later. > qualifiedSelection = typeName; > */ > > // find the outer most type > ISourceType outerType = sourceType; > ISourceType parent = sourceType.getEnclosingType(); > while (parent != null) { > outerType = parent; > parent = parent.getEnclosingType(); > } > // compute parse tree for this most outer type > CompilationResult result = new CompilationResult(outerType.getFileName(), 1, 1); > CompilationUnitDeclaration parsedUnit = > SourceTypeConverter > .buildCompilationUnit( > new ISourceType[] { outerType }, > false, > // don't need field and methods > true, // by default get member types > this.parser.problemReporter(), result); > > if (parsedUnit != null && parsedUnit.types != null) { > // find the type declaration that corresponds to the original source type > char[] packageName = sourceType.getPackageName(); > char[] sourceTypeName = sourceType.getQualifiedName(); > // the fully qualified name without the package name > if (packageName != null) { > // remove the package name if necessary > sourceTypeName = > CharOperation.subarray( > sourceType.getQualifiedName(), > packageName.length + 1, > sourceTypeName.length); > }; > TypeDeclaration typeDecl = > parsedUnit.declarationOfType(CharOperation.splitOn('.', sourceTypeName)); > if (typeDecl != null) { > > // add fake field with the type we're looking for > // note: since we didn't ask for fields above, there is no field defined yet > FieldDeclaration field = new FieldDeclaration(); > int dot; > if ((dot = CharOperation.lastIndexOf('.', typeName)) == -1) { > this.selectedIdentifier = typeName; > field.type = new SelectionOnSingleTypeReference(typeName, -1); > // position not used > } else { > char[][] previousIdentifiers = CharOperation.splitOn('.', typeName, 0, dot - 1); > char[] selectionIdentifier = > CharOperation.subarray(typeName, dot + 1, typeName.length); > this.selectedIdentifier = selectionIdentifier; > field.type = > new SelectionOnQualifiedTypeReference( > previousIdentifiers, > selectionIdentifier, > new long[previousIdentifiers.length + 1]); > } > field.name = "<fakeField>".toCharArray(); //$NON-NLS-1$ > typeDecl.fields = new FieldDeclaration[] { field }; > > // build bindings > lookupEnvironment.buildTypeBindings(parsedUnit); > if ((this.unitScope = parsedUnit.scope) != null) { > try { > // build fields > // note: this builds fields only in the parsed unit (the buildFieldsAndMethods flag is not passed along) > this.lookupEnvironment.completeTypeBindings(parsedUnit, true); > > // resolve > parsedUnit.scope.faultInTypes(); > parsedUnit.resolve(); > } catch (SelectionNodeFound e) { > if (e.binding != null) { > // if null then we found a problem in the selection node > selectFrom(e.binding); > } > } > } > } > } > // only reaches here if no selection could be derived from the parsed tree > // thus use the selected source and perform a textual type search > if (!acceptedAnswer) { > if (this.selectedIdentifier != null) { > nameEnvironment.findTypes(typeName, this); > } > } > } catch (AbortCompilation e) { // ignore this exception for now since it typically means we cannot find java.lang.Object > } finally { > qualifiedSelection = null; > reset(); > } > } > > // Check if a declaration got selected in this unit > private void selectDeclaration(CompilationUnitDeclaration compilationUnit){ > > // the selected identifier is not identical to the parser one (equals but not identical), > // for traversing the parse tree, the parser assist identifier is necessary for identitiy checks > char[] assistIdentifier = this.getParser().assistIdentifier(); > if (assistIdentifier == null) return; > > // iterate over the types > TypeDeclaration[] types = compilationUnit.types; > for (int i = 0, length = types == null ? 0 : types.length; i < length; i++){ > selectDeclaration(types[i], assistIdentifier); > } > } > > // Check if a declaration got selected in this type > private void selectDeclaration(TypeDeclaration typeDeclaration, char[] assistIdentifier){ > > if (typeDeclaration.name == assistIdentifier){ > throw new SelectionNodeFound(typeDeclaration.binding); > } > TypeDeclaration[] memberTypes = typeDeclaration.memberTypes; > for (int i = 0, length = memberTypes == null ? 0 : memberTypes.length; i < length; i++){ > selectDeclaration(memberTypes[i], assistIdentifier); > } > FieldDeclaration[] fields = typeDeclaration.fields; > for (int i = 0, length = fields == null ? 0 : fields.length; i < length; i++){ > if (fields[i].name == assistIdentifier){ > throw new SelectionNodeFound(fields[i].binding); > } > } > AbstractMethodDeclaration[] methods = typeDeclaration.methods; > for (int i = 0, length = methods == null ? 0 : methods.length; i < length; i++){ > if (methods[i].selector == assistIdentifier){ > throw new SelectionNodeFound(methods[i].binding); > } > } > } >}
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Raw
Actions:
View
Attachments on
bug 9785
: 363 |
364
|
365