Changeset 1229
- Timestamp:
- 07/14/08 01:05:01 (2 months ago)
- Files:
-
- trunk/descent.building/src/descent/building/BuilderLaunchDelegate.java (modified) (1 diff)
- trunk/descent.building/src/descent/building/IDBuilder.java (modified) (2 diffs)
- trunk/descent.building/src/descent/internal/building/BuilderUtil.java (modified) (9 diffs)
- trunk/descent.building/src/descent/internal/building/debuild/BuildRequest.java (modified) (2 diffs)
- trunk/descent.building/src/descent/internal/building/debuild/ConditionalEvaluator.java (added)
- trunk/descent.building/src/descent/internal/building/debuild/DebuildBuilder.java (modified) (7 diffs)
- trunk/descent.building/src/descent/internal/building/debuild/IncrementalConsistencyManager.java (added)
- trunk/descent.building/src/descent/internal/building/debuild/ObjectFileFactory.java (modified) (2 diffs)
- trunk/descent.building/src/descent/internal/building/debuild/RecursiveDependancyCollector.java (modified) (7 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/descent.building/src/descent/building/BuilderLaunchDelegate.java
r1197 r1229 35 35 throw error(String.format(DebuildMessages.BuilderLaunchDelegate_error_could_not_instantiate_builder, builderType.getIdentifier())); 36 36 37 builder.build(config, pm);37 builder.build(config, launch, pm); 38 38 } 39 39 trunk/descent.building/src/descent/building/IDBuilder.java
r1174 r1229 1 1 package descent.building; 2 2 3 import org.eclipse.core.runtime.CoreException;4 3 import org.eclipse.core.runtime.IProgressMonitor; 4 import org.eclipse.debug.core.ILaunch; 5 5 import org.eclipse.debug.core.ILaunchConfiguration; 6 6 … … 24 24 public interface IDBuilder 25 25 { 26 public String build(ILaunchConfiguration config, IProgressMonitor pm) throws CoreException; 26 public String build(ILaunchConfiguration config, ILaunch launch, 27 IProgressMonitor pm); 27 28 } trunk/descent.building/src/descent/internal/building/BuilderUtil.java
r1216 r1229 11 11 import org.eclipse.core.runtime.CoreException; 12 12 import org.eclipse.core.runtime.IPath; 13 import org.eclipse.core.runtime.IProgressMonitor; 14 import org.eclipse.core.runtime.NullProgressMonitor; 13 15 import org.eclipse.debug.core.ILaunchConfiguration; 14 16 … … 21 23 22 24 /** 23 * Static utility methods used throughout the builder 25 * Static utility methods used throughout the builder. THis class is not part of 26 * the debuild package, as it is designed to be used in the UI as well. 24 27 * 25 28 * @author Robert Fraser … … 28 31 public class BuilderUtil 29 32 { 33 //-------------------------------------------------------------------------- 34 // OS-Specific functionality 35 30 36 /** 31 37 * True if the current OS is Windows-based, false otherwise … … 41 47 static 42 48 { 49 // This needs to be initialized here to prevent constant folding 43 50 IS_WINDOWS = System.getProperty("os.name").startsWith("Windows"); //$NON-NLS-1$ //$NON-NLS-2$ 44 51 … … 60 67 } 61 68 } 69 70 //-------------------------------------------------------------------------- 71 // Version/debug identifier management 62 72 63 73 /** … … 100 110 101 111 /** 102 * Gets the absolute OS path for the given Eclipse path (with portable 103 * separarators, etc.). 104 * 105 * @param path 112 * Checks whether the given string is a valid D identifier. Valid D 113 * identifiers are the same as valid Java identifiers with the exception 114 * that Java allows '$'. 115 * 116 * @param id 106 117 * @return 107 118 */ 108 public static String getAbsolutePath(IPath path)109 {110 IResource res = ResourcesPlugin.getWorkspace().getRoot().findMember(path);111 if(null != res)112 path = res.getLocation();113 114 return path.toString();115 }116 117 119 public static boolean isValidIdentifier(String id) 118 120 { … … 129 131 } 130 132 133 private static boolean isValidIdStart(char c) 134 { 135 return Character.isJavaIdentifierStart(c) && !(c == '$'); 136 } 137 138 private static boolean isValidIdPart(char c) 139 { 140 return Character.isJavaIdentifierPart(c) && !(c == '$'); 141 } 142 143 //-------------------------------------------------------------------------- 144 // Compiler management 145 131 146 private static final CompilerInterfaceRegistry registry = 132 147 CompilerInterfaceRegistry.getInstance(); 133 148 134 149 /** 135 * Gets the compi elr interface for the given compiler.150 * Gets the compiler interface for the given compiler. 136 151 * 137 152 * @param compiler the compiler to get the interface for … … 158 173 } 159 174 160 private static boolean isValidIdStart(char c) 161 { 162 return Character.isJavaIdentifierStart(c) && !(c == '$'); 163 } 164 165 private static boolean isValidIdPart(char c) 166 { 167 return Character.isJavaIdentifierPart(c) && !(c == '$'); 168 } 175 /** 176 * Gets the VMInstall (compiler) associated with the given project 177 * 178 * @param project the project to get the compiler for 179 * @return the compiler associated with the project or null if either 180 * poject was null or no compielr is associated with project 181 */ 182 public static IVMInstall getVMInstall(IJavaProject project) 183 throws CoreException 184 { 185 if(null == project) 186 return null; 187 return JavaRuntime.getVMInstall(project); 188 } 189 190 //-------------------------------------------------------------------------- 191 // Wrappers for ILaunchConfiguration methods which hide the exceptions, 192 // since the exception will never be thrown 193 194 public static String getAttribute(ILaunchConfiguration config, String id, 195 String defaultValue) 196 { 197 String value = defaultValue; 198 try 199 { 200 value = config.getAttribute(id, defaultValue); 201 } 202 catch(CoreException e) { } 203 return value; 204 } 205 206 public static boolean getAttribute(ILaunchConfiguration config, String id, 207 boolean defaultValue) 208 { 209 boolean value = defaultValue; 210 try 211 { 212 value = config.getAttribute(id, defaultValue); 213 } 214 catch(CoreException e) { } 215 return value; 216 } 217 218 public static int getAttribute(ILaunchConfiguration config, String id, 219 int defaultValue) 220 { 221 int value = defaultValue; 222 try 223 { 224 value = config.getAttribute(id, defaultValue); 225 } 226 catch(CoreException e) { } 227 return value; 228 } 229 230 public static List getAttribute(ILaunchConfiguration config, String id, 231 List defaultValue) 232 { 233 List value = defaultValue; 234 try 235 { 236 value = config.getAttribute(id, defaultValue); 237 } 238 catch(CoreException e) { } 239 return value; 240 } 241 242 public static Map getAttribute(ILaunchConfiguration config, String id, 243 Map defaultValue) 244 { 245 Map value = defaultValue; 246 try 247 { 248 value = config.getAttribute(id, defaultValue); 249 } 250 catch(CoreException e) { } 251 return value; 252 } 253 254 public static Set getAttribute(ILaunchConfiguration config, String id, 255 Set defaultValue) 256 { 257 Set value = defaultValue; 258 try 259 { 260 value = config.getAttribute(id, defaultValue); 261 } 262 catch(CoreException e) { } 263 return value; 264 } 265 266 //-------------------------------------------------------------------------- 267 // Miscellaneous 268 269 /** 270 * A monitor for tasks that do not require 271 * 272 * Don't use this as the main null progress monitor, since its 273 * canceleld state is not garunteed. 274 */ 275 public static final IProgressMonitor NO_MONITOR = new NullProgressMonitor(); 169 276 170 277 /** … … 181 288 public static final Object[] EMPTY_ARRAY = new Object[] {}; 182 289 183 //-------------------------------------------------------------------------- 184 // Wrappers for ILaunchConfiguration methods which hide the exceptions, 185 // since the exception will never be thrown 186 187 public static String getAttribute(ILaunchConfiguration config, String id, 188 String defaultValue) 189 { 190 String value = defaultValue; 191 try 192 { 193 value = config.getAttribute(id, defaultValue); 194 } 195 catch(CoreException e) { } 196 return value; 197 } 198 199 public static boolean getAttribute(ILaunchConfiguration config, String id, 200 boolean defaultValue) 201 { 202 boolean value = defaultValue; 203 try 204 { 205 value = config.getAttribute(id, defaultValue); 206 } 207 catch(CoreException e) { } 208 return value; 209 } 210 211 public static int getAttribute(ILaunchConfiguration config, String id, 212 int defaultValue) 213 { 214 int value = defaultValue; 215 try 216 { 217 value = config.getAttribute(id, defaultValue); 218 } 219 catch(CoreException e) { } 220 return value; 221 } 222 223 public static List getAttribute(ILaunchConfiguration config, String id, 224 List defaultValue) 225 { 226 List value = defaultValue; 227 try 228 { 229 value = config.getAttribute(id, defaultValue); 230 } 231 catch(CoreException e) { } 232 return value; 233 } 234 235 public static Map getAttribute(ILaunchConfiguration config, String id, 236 Map defaultValue) 237 { 238 Map value = defaultValue; 239 try 240 { 241 value = config.getAttribute(id, defaultValue); 242 } 243 catch(CoreException e) { } 244 return value; 245 } 246 247 public static Set getAttribute(ILaunchConfiguration config, String id, 248 Set defaultValue) 249 { 250 Set value = defaultValue; 251 try 252 { 253 value = config.getAttribute(id, defaultValue); 254 } 255 catch(CoreException e) { } 256 return value; 257 } 258 259 public static IVMInstall getVMInstall(IJavaProject project) 260 throws CoreException 261 { 262 if(null == project) 263 return null; 264 return JavaRuntime.getVMInstall(project); 265 } 266 267 /** 268 * This method is needed since 269 * {@link ILaunchConfiguration#contentsEqual(ILaunchConfiguration)} compares 270 * the paths of launch configurations as well, and the getInfo method is not 271 * publicly available. 272 */ 273 public static boolean launchConfigsEqual(ILaunchConfiguration config, 274 ILaunchConfiguration other) throws CoreException 275 { 276 return config.getName().equals(other.getName()) && 277 config.getType().equals(other.getType()) && 278 config.getAttributes().equals(other.getAttributes()); 290 /** 291 * Gets the absolute OS path for the given Eclipse path (with portable 292 * separarators, etc.). 293 * 294 * @param path 295 * @return 296 */ 297 public static String getAbsolutePath(IPath path) 298 { 299 IResource res = ResourcesPlugin.getWorkspace().getRoot().findMember(path); 300 if(null != res) 301 path = res.getLocation(); 302 303 return path.toString(); 279 304 } 280 305 } trunk/descent.building/src/descent/internal/building/debuild/BuildRequest.java
r1216 r1229 314 314 "std.", 315 315 }; 316 316 317 private static final String[] tangoIgnored = new String[] 317 318 { … … 319 320 "gcc.", 320 321 }; 322 323 public final String[] getIgnoredModules() 324 { 325 // TODO 326 return phobosIgnored; 327 } 321 328 } trunk/descent.building/src/descent/internal/building/debuild/DebuildBuilder.java
r1216 r1229 7 7 import java.util.Set; 8 8 9 import org.eclipse.core.resources.IFile;10 import org.eclipse.core.resources.IFolder;11 import org.eclipse.core.resources.IResource;12 import org.eclipse.core.runtime.CoreException;13 9 import org.eclipse.core.runtime.IProgressMonitor; 14 10 import org.eclipse.core.runtime.NullProgressMonitor; 15 import org.eclipse.debug.core.DebugPlugin; 11 import org.eclipse.core.runtime.SubProgressMonitor; 12 import org.eclipse.debug.core.ILaunch; 16 13 import org.eclipse.debug.core.ILaunchConfiguration; 17 import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;18 14 19 15 import descent.core.IClasspathEntry; … … 23 19 import descent.internal.building.BuilderUtil; 24 20 import descent.building.IDBuilder; 21 import descent.building.compiler.IObjectFile; 25 22 26 23 public class DebuildBuilder implements IDBuilder … … 28 25 /* package */ static final boolean DEBUG = true; 29 26 30 /**31 * Note: don't use this as the main null progress monitor, since its32 * canceleld state is not garunteed.33 */34 private static final IProgressMonitor NO_MONITOR = new NullProgressMonitor();35 36 27 private BuildRequest req; 37 28 private ErrorReporter err; 38 29 private List<File> importPath; 39 30 40 public String build(ILaunchConfiguration config, I ProgressMonitor pm)41 throws CoreException31 public String build(ILaunchConfiguration config, ILaunch launch, 32 IProgressMonitor pm) 42 33 { 43 34 if(null == pm) … … 57 48 // If the launch configuration has changed, clear the output folder 58 49 // to do a full rebuild 59 managePrecomiledResources(); 50 IncrementalConsistencyManager consistencyMgr = 51 new IncrementalConsistencyManager(req); 52 consistencyMgr.checkConsistentState(); 60 53 pm.worked(5); // 10 61 54 … … 67 60 return null; 68 61 62 // Collect dependancies and create the associated object files 63 ObjectFileFactory objFactory = new ObjectFileFactory(req); 64 RecursiveDependancyCollector collector = 65 new RecursiveDependancyCollector(req, objFactory); 66 IObjectFile[] objectFiles = collector.getModules( 67 new SubProgressMonitor(pm, 35)); // 50 68 69 69 // TODO 70 70 return null; … … 73 73 { 74 74 err.projectError(e.getMessage()); 75 throw e; // TODO remove 75 if(DEBUG) 76 e.printStackTrace(); 77 return null; 76 78 } 77 79 catch(Exception e) … … 88 90 pm.done(); 89 91 } 90 }91 92 /**93 * If the launch configuration has changed, all pre-compiled resources need to94 * be removed and a full rebuild done (PERHAPS a more selective mechanism -- if95 * the user just changed the output file, for example, no rebuild is needed).96 * This method detects if the current launch configuration is different than the97 * existing launch configuration and if so deletes everything in the folder.98 *99 * @param config100 */101 private void managePrecomiledResources()102 {103 // TODO this doesn't work (it adds a new launch). FInd out if there's a way104 // not to, alternatively a new serialization mechanism needs to be created105 // (or maybe just somehow store the age/revision of the last change).106 try107 {108 // Check if the folder exists109 IFolder folder = req.getOutputResource();110 if(!folder.exists())111 {112 folder.create(true, true, NO_MONITOR);113 createConfigFile();114 return;115 }116 117 folder.refreshLocal(IResource.DEPTH_INFINITE, NO_MONITOR);118 IResource launchConfigFile = folder.findMember(getLaunchConfigFilename());119 if(null == launchConfigFile || !(launchConfigFile instanceof IFile))120 {121 System.out.println("File doesn't exist!");122 clearOutputFolder();123 createConfigFile();124 return;125 }126 127 ILaunchConfiguration launchConfig = DebugPlugin.getDefault().128 getLaunchManager().getLaunchConfiguration((IFile) launchConfigFile);129 if(!BuilderUtil.launchConfigsEqual(launchConfig, req.getLaunchConfig()))130 {131 System.out.println("Not equal!");132 clearOutputFolder();133 createConfigFile();134 return;135 }136 137 // If we get here, we can safely use any object files already138 // generated for incremental compilation.139 System.out.println("Contents saved!!!");140 }141 catch(CoreException e)142 {143 throw new DebuildException(String.format(144 "Error preparing output folder: %1$s", e.getMessage()));145 }146 147 }148 149 private String getLaunchConfigFilename()150 {151 return req.getLaunchConfig().getName().concat(".").152 concat(ILaunchConfiguration.LAUNCH_CONFIGURATION_FILE_EXTENSION);153 }154 155 private void createConfigFile() throws CoreException156 {157 ILaunchConfiguration config = req.getLaunchConfig();158 ILaunchConfigurationWorkingCopy copy = config.copy(config.getName());159 copy.setContainer(req.getOutputResource());160 copy.doSave();161 }162 163 private void clearOutputFolder() throws CoreException164 {165 System.out.println("Folder cleared!!!");166 167 IFolder outputFolder = req.getOutputResource();168 IResource[] members = outputFolder.members();169 for(IResource file : members)170 {171 try172 {173 file.delete(true, NO_MONITOR);174 }175 catch(CoreException e)176 {177 throw new DebuildException(String.format(178 "Error deleting resource %1$s: %2$s",179 file.getFullPath().toString(), e.getMessage()));180 }181 }182 92 } 183 93 trunk/descent.building/src/descent/internal/building/debuild/ObjectFileFactory.java
r1216 r1229 4 4 5 5 import descent.building.compiler.IObjectFile; 6 import descent.core.ICompilationUnit; 7 import descent.internal.building.BuilderUtil; 6 8 7 9 /* package */ final class ObjectFileFactory … … 36 38 } 37 39 } 40 41 private static final int MAX_FILENAME_LENGTH = 240; 42 43 private final BuildRequest req; 44 45 public ObjectFileFactory(BuildRequest req) 46 { 47 this.req = req; 48 } 49 50 public IObjectFile create(ICompilationUnit cu, 51 boolean isLibraryFile) 52 { 53 File inputFile = new File(BuilderUtil.getAbsolutePath(cu.getResource(). 54 getLocation())); 55 File outputFile = new File(req.getOutputLocation().getAbsolutePath() + 56 File.separator + getOutputFilename(cu)); 57 return new ObjectFile(inputFile, outputFile, isLibraryFile); 58 } 59 60 private static String getOutputFilename(ICompilationUnit cu) 61 { 62 String name = cu.getFullyQualifiedName().replace('.', '-') + "." + 63 BuilderUtil.EXTENSION_OBJECT_FILE; 64 int len = name.length(); 65 if(len > MAX_FILENAME_LENGTH) 66 name = name.substring(len - MAX_FILENAME_LENGTH); 67 return name; 68 } 38 69 } trunk/descent.building/src/descent/internal/building/debuild/RecursiveDependancyCollector.java
r1216 r1229 26 26 * Class that can recurse through dependencies to generate a list of all files 27 27 * that need to be compiled in a module. This class mainly exists to abstract 28 * the actual source analysis from the builder. The only method in this class 29 * that should be called externally is 30 * {@link #getObjectFiles(IJavaProject, ICompilationUnit[], IProgressMonitor)}, 31 * which will get the actual object files necessary using an instance of this 32 * class. 28 * the actual source analysis from the builder. 33 29 * 34 30 * @author Robert Fraser 35 31 */ 36 32 /* package */ class RecursiveDependancyCollector 37 { 38 /** 39 * Gets new {@link IObjectFile}s for all the compilation units given and any 40 * dependencies they may have. 41 * 42 * @param modules the initial compilation units to search from 43 * @param toIgnore a list of modules to ignore (not build). Entire packages 44 * can be ignored by ending the package name with a "." 45 * @param pm the progress monitor 46 * @return the object files (and dependancies) taht must be built 47 * for this project 48 */ 49 public static IObjectFile[] getObjectFiles( 50 BuildRequest req, 51 ObjectFileFactory factory, 52 String[] modules, 53 IProgressMonitor pm) 54 { 55 RecursiveDependancyCollector collector = new RecursiveDependancyCollector 56 (req, factory); 57 return collector.collect(modules, pm); 58 } 59 33 { 60 34 private final BuildRequest req; 61 35 private final ObjectFileFactory factory; 36 private final ConditionalEvaluator eval; 62 37 63 38 private final Map<String, IObjectFile> objectFiles = … … 71 46 private final Set<IJavaProject> visitedProjectAccumulator = new HashSet<IJavaProject>(); 72 47 73 // Shouldn't be constructed directly, use the getObjectFiles method instead 74 private RecursiveDependancyCollector(BuildRequest req, ObjectFileFactory factory) 48 /** 49 * Creates a new dependancy collectr 50 */ 51 public RecursiveDependancyCollector(BuildRequest req, ObjectFileFactory factory) 75 52 { 76 53 this.factory = factory; 77 54 this.req = req; 78 } 79 80 private IObjectFile[] collect(String[] modules, IProgressMonitor pm) 55 this.eval = new ConditionalEvaluator(req); 56 } 57 58 /** 59 * Gets new {@link IObjectFile}s for all the compilation units given and any 60 * dependencies they may have. 61 */ 62 public IObjectFile[] getModules(IProgressMonitor pm) 81 63 { 64 ICompilationUnit[] modules = req.getModules(); 82 65 try 83 66 { 84 67 pm.beginTask("Collecting dependencies", modules.length * 10); 85 68 86 for( String moduleName : modules)69 for(ICompilationUnit module : modules) 87 70 { 88 // Since this can take a long time, checking every so often for cancellation 89 // is good! 71 collectRecursive(module.getFullyQualifiedName(), pm); 72 pm.worked(10); 73 90 74 if(pm.isCanceled()) 91 return null; 92 93 collectRecursive(moduleName); 94 pm.worked(10); 75 return null; 95 76 } 96 77 … … 114 95 } 115 96 116 private void collectRecursive(String moduleName )97 private void collectRecursive(String moduleName, IProgressMonitor pm) 117 98 throws JavaModelException 118 { 99 { 100 // Check for user cancellation 101 if(pm.isCanceled()) 102 return; 103 119 104 // Check if we've already traversed this module 120 105 if(objectFiles.containsKey(moduleName)) 121 106 return; 122 107 123 // Check if it's a nodule that should be ignored124 /* TODOfor(String ignore : req.getIgnoredModules())108 // Check if it's a module that should be ignored 109 for(String ignore : req.getIgnoredModules()) 125 110 if(moduleName.startsWith(ignore)) 126 return; */111 return; 127 112 128 113 // Find the module … … 138 123 // Recurse through imports 139 124 for(String importedModule : getImports(module)) 140 collectRecursive(importedModule );125 collectRecursive(importedModule, pm); 141 126 } 142 127 … … 144 129 boolean isLibraryFile) 145 130 { 146 // TODO 147 return null; 131 return factory.create(cu, isLibraryFile); 148 132 } 149 133 … … 247 231 { 248 232 IConditional cond = (IConditional) element; 249 findImportsInElements(( isActive(cond) ? cond.getThenChildren() :233 findImportsInElements((eval.isActive(cond) ? cond.getThenChildren() : 250 234 cond.getElseChildren()), imports); 251 235 continue; … … 253 237 } 254 238 } 255 256 private boolean isActive(IConditional cond)257 {258 System.out.println("Conditional with displayString: " + cond.getElementName());259 // TODO check if it's active260 return true;261 }262 239 }
