35a3dc952b28c2f8d53284616052a904287e9cfa
[phpeclipse.git] / net.sourceforge.phpeclipse / src / net / sourceforge / phpdt / internal / codeassist / impl / Engine.java
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
7  * 
8  * Contributors:
9  *     IBM Corporation - initial API and implementation
10  ******************************************************************************/
11 package net.sourceforge.phpdt.internal.codeassist.impl;
12
13 import java.util.Map;
14
15 import net.sourceforge.phpdt.internal.codeassist.ISearchableNameEnvironment;
16 import net.sourceforge.phpdt.internal.compiler.*;
17 import net.sourceforge.phpdt.internal.compiler.env.*;
18
19 import net.sourceforge.phpdt.internal.compiler.ast.*;
20 import net.sourceforge.phpdt.internal.compiler.lookup.*;
21 import net.sourceforge.phpdt.internal.compiler.parser.*;
22 import net.sourceforge.phpdt.internal.compiler.util.CharOperation;
23 import net.sourceforge.phpdt.internal.compiler.impl.*;
24
25
26 public abstract class Engine implements ITypeRequestor {
27
28         public LookupEnvironment lookupEnvironment;
29         
30         protected CompilationUnitScope unitScope;
31         protected ISearchableNameEnvironment nameEnvironment;
32
33         public AssistOptions options;
34         public CompilerOptions compilerOptions; 
35         
36         public Engine(Map settings){
37                 this.options = new AssistOptions(settings);
38                 this.compilerOptions = new CompilerOptions(settings);
39         }
40         
41         /**
42          * Add an additional binary type
43          */
44         public void accept(IBinaryType binaryType, PackageBinding packageBinding) {
45                 lookupEnvironment.createBinaryTypeFrom(binaryType, packageBinding);
46         }
47
48         /**
49          * Add an additional compilation unit.
50          */
51         public void accept(ICompilationUnit sourceUnit) {
52                 CompilationResult result = new CompilationResult(sourceUnit, 1, 1, this.compilerOptions.maxProblemsPerUnit);
53                 CompilationUnitDeclaration parsedUnit =
54                         this.getParser().dietParse(sourceUnit, result);
55
56
57                 lookupEnvironment.buildTypeBindings(parsedUnit);
58                 lookupEnvironment.completeTypeBindings(parsedUnit, true);
59         }
60
61         /**
62          * Add additional source types (the first one is the requested type, the rest is formed by the
63          * secondary types defined in the same compilation unit).
64          */
65         public void accept(ISourceType[] sourceTypes, PackageBinding packageBinding) {
66                 CompilationResult result =
67                         new CompilationResult(sourceTypes[0].getFileName(), 1, 1, this.compilerOptions.maxProblemsPerUnit);
68                 CompilationUnitDeclaration unit =
69                         SourceTypeConverter.buildCompilationUnit(
70                                 sourceTypes,
71                                 true,
72                                 true,
73                                 lookupEnvironment.problemReporter,
74                                 result);
75
76                 if (unit != null) {
77                         lookupEnvironment.buildTypeBindings(unit);
78                         lookupEnvironment.completeTypeBindings(unit, true);
79                 }
80         }
81
82         public abstract AssistParser getParser();
83         
84         protected boolean mustQualifyType(
85                 char[] packageName,
86                 char[] typeName) {
87
88                 // If there are no types defined into the current CU yet.
89                 if (unitScope == null)
90                         return true;
91                         
92                 char[][] compoundPackageName = CharOperation.splitOn('.', packageName);
93                 char[] readableTypeName = CharOperation.concat(packageName, typeName, '.');
94
95                 if (CharOperation.equals(unitScope.fPackage.compoundName, compoundPackageName))
96                         return false;
97
98                 ImportBinding[] imports = unitScope.imports;
99                 if (imports != null){
100                         for (int i = 0, length = imports.length; i < length; i++) {
101                                 if (imports[i].onDemand) {
102                                         if (CharOperation.equals(imports[i].compoundName, compoundPackageName)) {
103                                                 for (int j = 0; j < imports.length; j++) {
104                                                         if(i != j){
105                                                                 if(imports[j].onDemand) {
106                                                                         if(nameEnvironment.findType(typeName, imports[j].compoundName) != null){
107                                                                                 return true;
108                                                                         }
109                                                                 } else {
110                                                                         if(CharOperation.equals(CharOperation.lastSegment(imports[j].readableName(), '.'), typeName)) {
111                                                                                 return true;    
112                                                                         }
113                                                                 }
114                                                         }
115                                                 }
116                                                 return false; // how do you match p1.p2.A.* ?
117                                         }
118         
119                                 } else
120         
121                                         if (CharOperation.equals(imports[i].readableName(), readableTypeName)) {
122                                                 return false;
123                                         }
124                         }
125                 }
126                 return true;
127         }
128
129         protected void parseMethod(CompilationUnitDeclaration unit, int position) {
130                 for (int i = unit.types.length; --i >= 0;) {
131                         TypeDeclaration type = unit.types[i];
132                         if (type.declarationSourceStart < position
133                                 && type.declarationSourceEnd >= position) {
134                                 getParser().scanner.setSource(
135                                         unit.compilationResult.compilationUnit.getContents());
136                                 parseMethod(type, unit, position);
137                                 return;
138                         }
139                 }
140         }
141
142         private void parseMethod(
143                 TypeDeclaration type,
144                 CompilationUnitDeclaration unit,
145                 int position) {
146                 //members
147                 TypeDeclaration[] memberTypes = type.memberTypes;
148                 if (memberTypes != null) {
149                         for (int i = memberTypes.length; --i >= 0;) {
150                                 TypeDeclaration memberType = memberTypes[i];
151                                 if (memberType.bodyStart > position)
152                                         continue;
153                                 if (memberType.declarationSourceEnd >= position) {
154                                         parseMethod(memberType, unit, position);
155                                         return;
156                                 }
157                         }
158                 }
159                 //methods
160                 AbstractMethodDeclaration[] methods = type.methods;
161                 if (methods != null) {
162                         for (int i = methods.length; --i >= 0;) {
163                                 AbstractMethodDeclaration method = methods[i];
164                                 if (method.bodyStart > position)
165                                         continue;
166                                 if (method.declarationSourceEnd >= position) {
167                                         getParser().parseBlockStatements(method, unit);
168                                         return;
169                                 }
170                         }
171                 }
172                 //initializers
173                 FieldDeclaration[] fields = type.fields;
174                 if (fields != null) {
175                         for (int i = fields.length; --i >= 0;) {
176                                 if (!(fields[i] instanceof Initializer))
177                                         continue;
178                                 Initializer initializer = (Initializer) fields[i];
179                                 if (initializer.bodyStart > position)
180                                         continue;
181                                 if (initializer.declarationSourceEnd >= position) {
182                                         getParser().parseBlockStatements(initializer, type, unit);
183                                         return;
184                                 }
185                         }
186                 }
187         }
188
189         protected void reset() {
190                 lookupEnvironment.reset();
191         }
192 }