1 /*******************************************************************************
2 * Copyright (c) 2000, 2001, 2002 International Business Machines Corp. and others.
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Common Public License v0.5
5 * which accompanies this distribution, and is available at
6 * http://www.eclipse.org/legal/cpl-v05.html
9 * IBM Corporation - initial API and implementation
10 ******************************************************************************/
11 package net.sourceforge.phpdt.internal.codeassist.impl;
15 import net.sourceforge.phpdt.internal.codeassist.ISearchableNameEnvironment;
16 import net.sourceforge.phpdt.internal.compiler.CompilationResult;
17 import net.sourceforge.phpdt.internal.compiler.ast.AbstractMethodDeclaration;
18 import net.sourceforge.phpdt.internal.compiler.ast.CompilationUnitDeclaration;
19 import net.sourceforge.phpdt.internal.compiler.ast.FieldDeclaration;
20 import net.sourceforge.phpdt.internal.compiler.ast.Initializer;
21 import net.sourceforge.phpdt.internal.compiler.ast.TypeDeclaration;
22 import net.sourceforge.phpdt.internal.compiler.env.IBinaryType;
23 import net.sourceforge.phpdt.internal.compiler.env.ICompilationUnit;
24 import net.sourceforge.phpdt.internal.compiler.env.ISourceType;
25 import net.sourceforge.phpdt.internal.compiler.impl.CompilerOptions;
26 import net.sourceforge.phpdt.internal.compiler.impl.ITypeRequestor;
27 import net.sourceforge.phpdt.internal.compiler.lookup.CompilationUnitScope;
28 import net.sourceforge.phpdt.internal.compiler.lookup.ImportBinding;
29 import net.sourceforge.phpdt.internal.compiler.lookup.LookupEnvironment;
30 import net.sourceforge.phpdt.internal.compiler.lookup.PackageBinding;
31 import net.sourceforge.phpdt.internal.compiler.parser.SourceTypeConverter;
32 import net.sourceforge.phpdt.internal.compiler.util.CharOperation;
35 public abstract class Engine implements ITypeRequestor {
37 public LookupEnvironment lookupEnvironment;
39 protected CompilationUnitScope unitScope;
40 protected ISearchableNameEnvironment nameEnvironment;
42 public AssistOptions options;
43 public CompilerOptions compilerOptions;
45 public Engine(Map settings){
46 this.options = new AssistOptions(settings);
47 this.compilerOptions = new CompilerOptions(settings);
51 * Add an additional binary type
53 public void accept(IBinaryType binaryType, PackageBinding packageBinding) {
54 lookupEnvironment.createBinaryTypeFrom(binaryType, packageBinding);
58 * Add an additional compilation unit.
60 public void accept(ICompilationUnit sourceUnit) {
61 CompilationResult result = new CompilationResult(sourceUnit, 1, 1, this.compilerOptions.maxProblemsPerUnit);
62 CompilationUnitDeclaration parsedUnit =
63 this.getParser().dietParse(sourceUnit, result);
66 lookupEnvironment.buildTypeBindings(parsedUnit);
67 lookupEnvironment.completeTypeBindings(parsedUnit, true);
71 * Add additional source types (the first one is the requested type, the rest is formed by the
72 * secondary types defined in the same compilation unit).
74 public void accept(ISourceType[] sourceTypes, PackageBinding packageBinding) {
75 CompilationResult result =
76 new CompilationResult(sourceTypes[0].getFileName(), 1, 1, this.compilerOptions.maxProblemsPerUnit);
77 CompilationUnitDeclaration unit =
78 SourceTypeConverter.buildCompilationUnit(
82 lookupEnvironment.problemReporter,
86 lookupEnvironment.buildTypeBindings(unit);
87 lookupEnvironment.completeTypeBindings(unit, true);
91 public abstract AssistParser getParser();
93 protected boolean mustQualifyType(
97 // If there are no types defined into the current CU yet.
98 if (unitScope == null)
101 char[][] compoundPackageName = CharOperation.splitOn('.', packageName);
102 char[] readableTypeName = CharOperation.concat(packageName, typeName, '.');
104 if (CharOperation.equals(unitScope.fPackage.compoundName, compoundPackageName))
107 ImportBinding[] imports = unitScope.imports;
108 if (imports != null){
109 for (int i = 0, length = imports.length; i < length; i++) {
110 if (imports[i].onDemand) {
111 if (CharOperation.equals(imports[i].compoundName, compoundPackageName)) {
112 for (int j = 0; j < imports.length; j++) {
114 if(imports[j].onDemand) {
115 if(nameEnvironment.findType(typeName, imports[j].compoundName) != null){
119 if(CharOperation.equals(CharOperation.lastSegment(imports[j].readableName(), '.'), typeName)) {
125 return false; // how do you match p1.p2.A.* ?
130 if (CharOperation.equals(imports[i].readableName(), readableTypeName)) {
138 protected void parseMethod(CompilationUnitDeclaration unit, int position) {
139 for (int i = unit.types.length; --i >= 0;) {
140 TypeDeclaration type = unit.types[i];
141 if (type.declarationSourceStart < position
142 && type.declarationSourceEnd >= position) {
143 getParser().scanner.setSource(
144 unit.compilationResult.compilationUnit.getContents());
145 parseMethod(type, unit, position);
151 private void parseMethod(
152 TypeDeclaration type,
153 CompilationUnitDeclaration unit,
156 TypeDeclaration[] memberTypes = type.memberTypes;
157 if (memberTypes != null) {
158 for (int i = memberTypes.length; --i >= 0;) {
159 TypeDeclaration memberType = memberTypes[i];
160 if (memberType.bodyStart > position)
162 if (memberType.declarationSourceEnd >= position) {
163 parseMethod(memberType, unit, position);
169 AbstractMethodDeclaration[] methods = type.methods;
170 if (methods != null) {
171 for (int i = methods.length; --i >= 0;) {
172 AbstractMethodDeclaration method = methods[i];
173 if (method.bodyStart > position)
175 if (method.declarationSourceEnd >= position) {
176 getParser().parseBlockStatements(method, unit);
182 FieldDeclaration[] fields = type.fields;
183 if (fields != null) {
184 for (int i = fields.length; --i >= 0;) {
185 if (!(fields[i] instanceof Initializer))
187 Initializer initializer = (Initializer) fields[i];
188 if (initializer.bodyStart > position)
190 if (initializer.declarationSourceEnd >= position) {
191 getParser().parseBlockStatements(initializer, type, unit);
198 protected void reset() {
199 lookupEnvironment.reset();