|
27 | 27 | import org.eclipse.jdt.core.*; |
28 | 28 | import org.eclipse.jdt.core.compiler.CategorizedProblem; |
29 | 29 | import org.eclipse.jdt.core.compiler.CharOperation; |
| 30 | +import org.eclipse.jdt.core.dom.CompilationUnitResolver.IntArrayList; |
30 | 31 | import org.eclipse.jdt.internal.compiler.ast.ConstructorDeclaration; |
31 | 32 | import org.eclipse.jdt.internal.compiler.ast.ExplicitConstructorCall; |
32 | 33 | import org.eclipse.jdt.internal.compiler.batch.FileSystem.Classpath; |
|
38 | 39 | import org.eclipse.jdt.internal.compiler.parser.RecoveryScanner; |
39 | 40 | import org.eclipse.jdt.internal.compiler.parser.RecoveryScannerData; |
40 | 41 | import org.eclipse.jdt.internal.compiler.parser.Scanner; |
| 42 | +import org.eclipse.jdt.internal.compiler.util.HashtableOfObjectToInt; |
41 | 43 | import org.eclipse.jdt.internal.compiler.util.SuffixConstants; |
42 | | -import org.eclipse.jdt.internal.core.BasicCompilationUnit; |
43 | | -import org.eclipse.jdt.internal.core.BinaryType; |
44 | | -import org.eclipse.jdt.internal.core.ClassFileWorkingCopy; |
45 | | -import org.eclipse.jdt.internal.core.DefaultWorkingCopyOwner; |
46 | | -import org.eclipse.jdt.internal.core.JavaModelManager; |
47 | | -import org.eclipse.jdt.internal.core.PackageFragment; |
| 44 | +import org.eclipse.jdt.internal.core.*; |
48 | 45 | import org.eclipse.jdt.internal.core.dom.ICompilationUnitResolver; |
49 | 46 | import org.eclipse.jdt.internal.core.dom.util.DOMASTUtil; |
50 | 47 | import org.eclipse.jdt.internal.core.util.CodeSnippetParsingUtil; |
| 48 | +import org.eclipse.jdt.internal.core.util.DOMFinder; |
51 | 49 | import org.eclipse.jdt.internal.core.util.RecordedParsingInformation; |
52 | 50 | import org.eclipse.jdt.internal.core.util.Util; |
53 | 51 |
|
@@ -1166,13 +1164,98 @@ public IBinding[] createBindings(IJavaElement[] elements, IProgressMonitor monit |
1166 | 1164 | if ((this.bits & CompilationUnitResolver.IGNORE_METHOD_BODIES) != 0) { |
1167 | 1165 | flags |= ICompilationUnit.IGNORE_METHOD_BODIES; |
1168 | 1166 | } |
1169 | | - return CompilationUnitResolver.resolve(elements, this.apiLevel, this.compilerOptions, this.project, this.workingCopyOwner, flags, monitor); |
| 1167 | + |
| 1168 | + return resolve(elements, this.apiLevel, this.compilerOptions, this.project, this.workingCopyOwner, flags, this.unitResolver, monitor); |
1170 | 1169 | } finally { |
1171 | 1170 | // reset to defaults to allow reuse (and avoid leaking) |
1172 | 1171 | initializeDefaults(); |
1173 | 1172 | } |
1174 | 1173 | } |
1175 | 1174 |
|
| 1175 | + |
| 1176 | + static IBinding[] resolve( |
| 1177 | + final IJavaElement[] elements, |
| 1178 | + int apiLevel, |
| 1179 | + Map<String,String> compilerOptions, |
| 1180 | + IJavaProject javaProject, |
| 1181 | + WorkingCopyOwner owner, |
| 1182 | + int flags, |
| 1183 | + ICompilationUnitResolver unitResolver, |
| 1184 | + IProgressMonitor monitor) { |
| 1185 | + |
| 1186 | + final int length = elements.length; |
| 1187 | + final HashMap<IJavaElement, IntArrayList> sourceElementPositions = new HashMap<>(); // a map from ICompilationUnit to int[] (positions in elements) |
| 1188 | + int cuNumber = 0; |
| 1189 | + final HashtableOfObjectToInt binaryElementPositions = new HashtableOfObjectToInt(); // a map from String (binding key) to int (position in elements) |
| 1190 | + for (int i = 0; i < length; i++) { |
| 1191 | + IJavaElement element = elements[i]; |
| 1192 | + if (!(element instanceof SourceRefElement)) |
| 1193 | + throw new IllegalStateException(element + " is not part of a compilation unit or class file"); //$NON-NLS-1$ |
| 1194 | + IJavaElement cu = element.getAncestor(IJavaElement.COMPILATION_UNIT); |
| 1195 | + if (cu != null) { |
| 1196 | + // source member |
| 1197 | + IntArrayList intList = sourceElementPositions.get(cu); |
| 1198 | + if (intList == null) { |
| 1199 | + sourceElementPositions.put(cu, intList = new IntArrayList()); |
| 1200 | + cuNumber++; |
| 1201 | + } |
| 1202 | + intList.add(i); |
| 1203 | + } else { |
| 1204 | + // binary member or method argument |
| 1205 | + try { |
| 1206 | + String key; |
| 1207 | + if (element instanceof BinaryMember) |
| 1208 | + key = ((BinaryMember) element).getKey(true/*open to get resolved info*/); |
| 1209 | + else if (element instanceof LocalVariable) |
| 1210 | + key = ((LocalVariable) element).getKey(true/*open to get resolved info*/); |
| 1211 | + else if (element instanceof org.eclipse.jdt.internal.core.TypeParameter) |
| 1212 | + key = ((org.eclipse.jdt.internal.core.TypeParameter) element).getKey(true/*open to get resolved info*/); |
| 1213 | + else if (element instanceof BinaryModule) |
| 1214 | + key = ((BinaryModule) element).getKey(true); |
| 1215 | + else |
| 1216 | + throw new IllegalArgumentException(element + " has an unexpected type"); //$NON-NLS-1$ |
| 1217 | + binaryElementPositions.put(key, i); |
| 1218 | + } catch (JavaModelException e) { |
| 1219 | + throw new IllegalArgumentException(element + " does not exist", e); //$NON-NLS-1$ |
| 1220 | + } |
| 1221 | + } |
| 1222 | + } |
| 1223 | + ICompilationUnit[] cus = new ICompilationUnit[cuNumber]; |
| 1224 | + sourceElementPositions.keySet().toArray(cus); |
| 1225 | + |
| 1226 | + int bindingKeyNumber = binaryElementPositions.size(); |
| 1227 | + String[] bindingKeys = new String[bindingKeyNumber]; |
| 1228 | + binaryElementPositions.keysToArray(bindingKeys); |
| 1229 | + |
| 1230 | + class Requestor extends ASTRequestor { |
| 1231 | + IBinding[] bindings = new IBinding[length]; |
| 1232 | + @Override |
| 1233 | + public void acceptAST(ICompilationUnit source, CompilationUnit ast) { |
| 1234 | + // TODO (jerome) optimize to visit the AST only once |
| 1235 | + IntArrayList intList = sourceElementPositions.get(source); |
| 1236 | + for (int i = 0; i < intList.length; i++) { |
| 1237 | + final int index = intList.list[i]; |
| 1238 | + SourceRefElement element = (SourceRefElement) elements[index]; |
| 1239 | + DOMFinder finder = new DOMFinder(ast, element, true/*resolve binding*/); |
| 1240 | + try { |
| 1241 | + finder.search(); |
| 1242 | + } catch (JavaModelException e) { |
| 1243 | + throw new IllegalArgumentException(element + " does not exist", e); //$NON-NLS-1$ |
| 1244 | + } |
| 1245 | + this.bindings[index] = finder.foundBinding; |
| 1246 | + } |
| 1247 | + } |
| 1248 | + @Override |
| 1249 | + public void acceptBinding(String bindingKey, IBinding binding) { |
| 1250 | + int index = binaryElementPositions.get(bindingKey); |
| 1251 | + this.bindings[index] = binding; |
| 1252 | + } |
| 1253 | + } |
| 1254 | + Requestor requestor = new Requestor(); |
| 1255 | + unitResolver.resolve(cus, bindingKeys, requestor, apiLevel, compilerOptions, javaProject, owner, flags, monitor); |
| 1256 | + return requestor.bindings; |
| 1257 | + } |
| 1258 | + |
1176 | 1259 | private ASTNode internalCreateAST(IProgressMonitor monitor) { |
1177 | 1260 | return JavaModelManager.cacheZipFiles(() -> internalCreateASTCached(monitor)); |
1178 | 1261 | } |
|
0 commit comments