public BuildResultStatus rebuild(TreeLogger logger) { logger = logger.branch(TreeLogger.INFO, "Performing an incremental rebuild"); ResourceOracleImpl.clearCache(); ZipFileClassPathEntry.clearCache(); ModuleDefLoader.clearModuleCache(); ResourceGeneratorUtilImpl.clearGeneratedFilesByName(); long beforeComputeOutputFreshnessMs = System.currentTimeMillis(); forgetAllOutputFreshness(); rootBuildTarget.computeOutputFreshness(logger); long computeOutputFreshnessDurationMs = System.currentTimeMillis() - beforeComputeOutputFreshnessMs; logger.log( TreeLogger.INFO, String.format( "%.3fs -- Computing per-target output freshness", computeOutputFreshnessDurationMs / 1000d)); if (rootBuildTarget.isOutputFreshAndGood()) { logger.log(TreeLogger.INFO, NO_FILES_HAVE_CHANGED); return BuildResultStatus.SUCCESS_NO_CHANGES; } TreeLogger branch = logger.branch(TreeLogger.INFO, "Compiling target graph"); boolean success = rootBuildTarget.link(branch); return BuildResultStatus.get(success); }
/** Loads the module and configures it for SuperDevMode. (Does not restrict permutations.) */ private ModuleDef loadModule(TreeLogger logger) throws UnableToCompleteException { // make sure we get the latest version of any modified jar ZipFileClassPathEntry.clearCache(); ResourceOracleImpl.clearCache(); ResourceLoader resources = ResourceLoaders.forClassLoader(Thread.currentThread()); resources = ResourceLoaders.forPathAndFallback(options.getSourcePath(), resources); this.resourceLoader.set(resources); // ModuleDefLoader.loadFromResources() checks for modified .gwt.xml files. ModuleDef moduleDef = ModuleDefLoader.loadFromResources( logger, compilerContext, inputModuleName, resources, true); compilerContext = compilerContextBuilder.module(moduleDef).build(); // Undo all permutation restriction customizations from previous compiles. for (BindingProperty bindingProperty : moduleDef.getProperties().getBindingProperties()) { String[] allowedValues = bindingProperty.getAllowedValues(bindingProperty.getRootCondition()); bindingProperty.setRootGeneratedValues(allowedValues); } // A snapshot of the module's configuration before we modified it. ConfigProps config = new ConfigProps(moduleDef); // We need a cross-site linker. Automatically replace the default linker. if (IFrameLinker.class.isAssignableFrom(moduleDef.getActivePrimaryLinker())) { moduleDef.addLinker("xsiframe"); } // Check that we have a compatible linker. Class<? extends Linker> linker = moduleDef.getActivePrimaryLinker(); if (!CrossSiteIframeLinker.class.isAssignableFrom(linker)) { logger.log( TreeLogger.ERROR, "linkers other than CrossSiteIFrameLinker aren't supported. Found: " + linker.getName()); throw new UnableToCompleteException(); } // Deactivate precompress linker. if (moduleDef.deactivateLinker("precompress")) { logger.log(TreeLogger.WARN, "Deactivated PrecompressLinker"); } // Print a nice error if the superdevmode hook isn't present if (config.getStrings("devModeRedirectEnabled").isEmpty()) { throw new RuntimeException( "devModeRedirectEnabled isn't set for module: " + moduleDef.getName()); } // Disable the redirect hook here to make sure we don't have an infinite loop. // (There is another check in the JavaScript, but just in case.) overrideConfig(moduleDef, "devModeRedirectEnabled", "false"); // Turn off "installCode" if it's on because it makes debugging harder. // (If it's already off, don't change anything.) if (config.getBoolean("installCode", true)) { overrideConfig(moduleDef, "installCode", "false"); // Make sure installScriptJs is set to the default for compiling without installCode. overrideConfig( moduleDef, "installScriptJs", "com/google/gwt/core/ext/linker/impl/installScriptDirect.js"); } // override computeScriptBase.js to enable the "Compile" button overrideConfig( moduleDef, "computeScriptBaseJs", "com/google/gwt/dev/codeserver/computeScriptBase.js"); // Fix bug with SDM and Chrome 24+ where //@ sourceURL directives cause X-SourceMap header to be // ignored // Frustratingly, Chrome won't canonicalize a relative URL overrideConfig( moduleDef, "includeSourceMapUrl", "http://" + serverPrefix + SourceHandler.sourceMapLocationTemplate(moduleDef.getName())); // If present, set some config properties back to defaults. // (Needed for Google's server-side linker.) maybeOverrideConfig(moduleDef, "includeBootstrapInPrimaryFragment", "false"); maybeOverrideConfig( moduleDef, "permutationsJs", "com/google/gwt/core/ext/linker/impl/permutations.js"); maybeOverrideConfig( moduleDef, "propertiesJs", "com/google/gwt/core/ext/linker/impl/properties.js"); if (options.isIncrementalCompileEnabled()) { // CSSResourceGenerator needs to produce stable, unique naming for its input. // Currently on default settings CssResourceGenerator's obfuscation depends on // whole world knowledge and thus will produce collision in obfuscated mode, since in // incremental compiles that information is not available. // // TODO(dankurka): Once we do proper stable hashing of classes in CssResourceGenerator, we // can probably replace / remove this. maybeOverrideConfig(moduleDef, "CssResource.style", "stable"); } overrideBinding(moduleDef, "compiler.useSourceMaps", "true"); overrideBinding(moduleDef, "compiler.useSymbolMaps", "false"); overrideBinding(moduleDef, "superdevmode", "on"); return moduleDef; }