]> git.uio.no Git - ifi-stolz-refaktor.git/blob - case-study/jdt-before/core extension/org/eclipse/jdt/internal/corext/dom/ASTBatchParser.java
Case Study: adding data and statistics
[ifi-stolz-refaktor.git] / case-study / jdt-before / core extension / org / eclipse / jdt / internal / corext / dom / ASTBatchParser.java
1 /*******************************************************************************
2  * Copyright (c) 2007, 2011 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  *     IBM Corporation - initial API and implementation
10  *******************************************************************************/
11 package org.eclipse.jdt.internal.corext.dom;
12
13 import java.util.ArrayList;
14 import java.util.Arrays;
15 import java.util.Collection;
16 import java.util.Hashtable;
17 import java.util.Iterator;
18 import java.util.List;
19
20 import org.eclipse.core.runtime.IProgressMonitor;
21 import org.eclipse.core.runtime.NullProgressMonitor;
22 import org.eclipse.core.runtime.SubProgressMonitor;
23
24 import org.eclipse.jdt.core.ICompilationUnit;
25 import org.eclipse.jdt.core.IJavaProject;
26 import org.eclipse.jdt.core.dom.ASTParser;
27 import org.eclipse.jdt.core.dom.ASTRequestor;
28 import org.eclipse.jdt.core.dom.IBinding;
29
30 import org.eclipse.jdt.internal.ui.javaeditor.ASTProvider;
31
32 /**
33  * Creates AST from a set of compilation units. Uses the
34  * batch parser. Splits the set of compilation units in subsets
35  * such that it is unlikely that a out of memory exception will occur.
36  *
37  * @since 3.4
38  */
39 public class ASTBatchParser {
40
41         private static final int MAX_AT_ONCE;
42         static {
43                 long maxMemory= Runtime.getRuntime().maxMemory();
44                 int ratio= (int) Math.round((double) maxMemory / (64 * 0x100000));
45                 switch (ratio) {
46                         case 0:
47                                 MAX_AT_ONCE= 25;
48                                 break;
49                         case 1:
50                                 MAX_AT_ONCE= 100;
51                                 break;
52                         case 2:
53                                 MAX_AT_ONCE= 200;
54                                 break;
55                         case 3:
56                                 MAX_AT_ONCE= 300;
57                                 break;
58                         case 4:
59                                 MAX_AT_ONCE= 400;
60                                 break;
61                         default:
62                                 MAX_AT_ONCE= 500;
63                                 break;
64                 }
65         }
66
67         /**
68          * Creates ASTs for each compilation unit in <code>units</code>.
69          * <p>
70          * <code>ASTRequestor.acceptAST</code> is called in no particular order to
71          * pass the compilation unit and the corresponding AST to <code>requestor</code>.
72          * </p>
73          * <p>
74          * The <code>bindingKeys</code> parameter specifies bindings keys
75          * ({@link IBinding#getKey()}) that are to be looked up.
76          * </p>
77          *
78          * @param compilationUnits the compilation units to create ASTs for
79          * @param bindingKeys the binding keys to create bindings for
80          * @param requestor the AST requestor that collects abstract syntax trees and bindings
81          * @param monitor the progress monitor used to report progress and request cancelation,
82          *   or <code>null</code> if none
83          * @see ASTParser#createASTs(ICompilationUnit[], String[], ASTRequestor, IProgressMonitor)
84          */
85         public final void createASTs(ICompilationUnit[] compilationUnits, String[] bindingKeys, ASTRequestor requestor, IProgressMonitor monitor) {
86                 if (compilationUnits.length == 0)
87                         return;
88
89                 if (monitor == null)
90                         monitor= new NullProgressMonitor();
91
92                 monitor.beginTask("", compilationUnits.length); //$NON-NLS-1$
93                 try {
94
95                         ICompilationUnit[][] splited= splitByProject(compilationUnits);
96                         for (int i= 0; i < splited.length; i++) {
97                                 ICompilationUnit[] units= splited[i];
98
99                                 if (units.length <= MAX_AT_ONCE) {
100                                         createParser(units[0].getJavaProject()).createASTs(units, bindingKeys, requestor, new SubProgressMonitor(monitor, units.length));
101                                 } else {
102                                         List<ICompilationUnit> list= Arrays.asList(units);
103                                         int end= 0;
104                                         int cursor= 0;
105                                         while (cursor < units.length) {
106                                                 end= Math.min(end + MAX_AT_ONCE, units.length);
107                                                 List<ICompilationUnit> toParse= list.subList(cursor, end);
108
109                                                 createParser(units[0].getJavaProject()).createASTs(toParse.toArray(new ICompilationUnit[toParse.size()]), bindingKeys, requestor,
110                                                                 new SubProgressMonitor(monitor, toParse.size()));
111                                                 cursor= end;
112                                         }
113                                 }
114                         }
115                 } finally {
116                         monitor.done();
117                 }
118         }
119
120         /**
121          * Creates a new parser which can be used to create ASTs
122          * for compilation units in <code>project</code>
123          * <p>
124          * Subclasses may override
125          * </p>
126          *
127          * @param project the project for which ASTs are been generated
128          * @return an AST parser capable of creating ASTs of compilation units in project
129          */
130         protected ASTParser createParser(IJavaProject project) {
131                 ASTParser result= ASTParser.newParser(ASTProvider.SHARED_AST_LEVEL);
132                 result.setResolveBindings(true);
133                 result.setProject(project);
134
135                 return result;
136         }
137
138         private static ICompilationUnit[][] splitByProject(ICompilationUnit[] units) {
139                 if (hasOnlyOneProject(units))
140                         return new ICompilationUnit[][] { units };
141
142                 Hashtable<IJavaProject, ArrayList<ICompilationUnit>> projectTable= new Hashtable<IJavaProject, ArrayList<ICompilationUnit>>();
143
144                 for (int i= 0; i < units.length; i++) {
145                         ICompilationUnit unit= units[i];
146                         ArrayList<ICompilationUnit> list= projectTable.get(unit.getJavaProject());
147                         if (list == null) {
148                                 list= new ArrayList<ICompilationUnit>();
149                                 projectTable.put(unit.getJavaProject(), list);
150                         }
151                         list.add(unit);
152                 }
153
154                 Collection<ArrayList<ICompilationUnit>> values= projectTable.values();
155
156                 ICompilationUnit[][] result= new ICompilationUnit[values.size()][];
157                 int i= 0;
158                 for (Iterator<ArrayList<ICompilationUnit>> iterator= values.iterator(); iterator.hasNext();) {
159                         ArrayList<ICompilationUnit> cus= iterator.next();
160                         result[i]= cus.toArray(new ICompilationUnit[cus.size()]);
161                         i++;
162                 }
163
164                 return result;
165         }
166
167         private static boolean hasOnlyOneProject(ICompilationUnit[] units) {
168                 IJavaProject javaProject= units[0].getJavaProject();
169                 for (int i= 1; i < units.length; i++) {
170                         if (!javaProject.equals(units[i].getJavaProject()))
171                                 return false;
172                 }
173
174                 return true;
175         }
176 }