Revision: 6857 Author: [email protected] Date: Wed Nov 11 16:03:56 2009 Log: Sandboxes AbstractCompiler so that the backreference can be detached from internal JDT types.
Failure to do this ultimately creates a reference from JDT CUDs to WebModeCompilerFrontEnd, which pins the current CompilationState and TypeOracle in memory. Review by: bobv http://code.google.com/p/google-web-toolkit/source/detail?r=6857 Deleted: /trunk/dev/core/src/com/google/gwt/dev/util/log/ThreadLocalTreeLoggerProxy.java Modified: /trunk/dev/core/src/com/google/gwt/dev/jdt/AbstractCompiler.java /trunk/dev/core/src/com/google/gwt/dev/jdt/WebModeCompilerFrontEnd.java ======================================= --- /trunk/dev/core/src/com/google/gwt/dev/util/log/ThreadLocalTreeLoggerProxy.java Tue Apr 1 16:48:44 2008 +++ /dev/null @@ -1,93 +0,0 @@ -/* - * Copyright 2007 Google Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations under - * the License. - */ -package com.google.gwt.dev.util.log; - -import com.google.gwt.core.ext.TreeLogger; - -/** - * An internal implementation support class that creates a - * {...@link com.google.gwt.server.internal.TreeLogger} that wraps another - * TreeLogger to allow for the underlying logger to be redirected per thread. It - * can be useful for situations where it is not practical to pass in a logger as - * a parameter, such as when interfacing with third-party classes. - */ -public final class ThreadLocalTreeLoggerProxy extends TreeLogger { - - private static final ThreadLocal<TreeLogger> perThreadLogger = new ThreadLocal<TreeLogger>(); - - public ThreadLocalTreeLoggerProxy() { - this(null); - } - - public ThreadLocalTreeLoggerProxy(TreeLogger logger) { - push(logger); - } - - /** - * Delegates the branch to the thread-local logger if one is present. - * Otherwise, the log entry is discarded and <code>this</code> is returned. - */ - @Override - public TreeLogger branch(Type type, String msg, Throwable caught, - HelpInfo helpInfo) { - TreeLogger logger = perThreadLogger.get(); - if (logger != null) { - return logger.branch(type, msg, caught, helpInfo); - } else { - return this; - } - } - - /** - * Delegates the check to the thread-local logger if one is present. - * - * @return relays the return value of the wrapped logger if one exists, or - * returns <code>false</code> otherwise - */ - public boolean isLoggable(Type type) { - TreeLogger logger = perThreadLogger.get(); - if (logger != null) { - return logger.isLoggable(type); - } else { - return false; - } - } - - /** - * Delegates the log to the thread-local logger if one is present. Otherwise, - * the log entry is discarded. - */ - @Override - public void log(Type type, String msg, Throwable caught, HelpInfo helpInfo) { - TreeLogger logger = perThreadLogger.get(); - if (logger != null) { - logger.log(type, msg, caught, helpInfo); - } - } - - public void pop(TreeLogger oldLogger) { - perThreadLogger.set(oldLogger); - } - - /** - * Sets the logger to which calls are redirected for the current thread. - */ - public TreeLogger push(TreeLogger logger) { - TreeLogger old = perThreadLogger.get(); - perThreadLogger.set(logger); - return old; - } -} ======================================= --- /trunk/dev/core/src/com/google/gwt/dev/jdt/AbstractCompiler.java Tue Nov 10 20:42:30 2009 +++ /trunk/dev/core/src/com/google/gwt/dev/jdt/AbstractCompiler.java Wed Nov 11 16:03:56 2009 @@ -26,7 +26,6 @@ import com.google.gwt.dev.util.Empty; import com.google.gwt.dev.util.PerfLogger; import com.google.gwt.dev.util.Util; -import com.google.gwt.dev.util.log.ThreadLocalTreeLoggerProxy; import org.eclipse.jdt.core.compiler.CharOperation; import org.eclipse.jdt.core.compiler.IProblem; @@ -71,6 +70,7 @@ this.unit = unit; } + @SuppressWarnings("deprecation") public char[] getContents() { return unit.getSource().toCharArray(); } @@ -87,10 +87,6 @@ String packageName = Shared.getPackageName(unit.getTypeName()); return CharOperation.splitOn('.', packageName.toCharArray()); } - - public CompilationUnit getUnit() { - return unit; - } @Override public String toString() { @@ -99,306 +95,375 @@ } /** - * Adapted to hook the processing of compilation unit declarations so as to be - * able to add additional compilation units based on the results of - * previously-compiled ones. Examples of cases where this is useful include - * classes referenced only from JSNI and <code>GWT.create</code>. + * Shields {...@link AbstractCompiler} so it can be garbage collected at the end + * of a compile. */ - private class CompilerImpl extends Compiler { - - private Set<CompilationUnitDeclaration> cuds; - private long jdtProcessNanos; - - public CompilerImpl(INameEnvironment environment, - IErrorHandlingPolicy policy, CompilerOptions compilerOptions, - ICompilerRequestor requestor, IProblemFactory problemFactory) { - super(environment, policy, compilerOptions, requestor, problemFactory); - } - - @Override - public void compile(ICompilationUnit[] sourceUnits) { - jdtProcessNanos = 0; - super.compile(sourceUnits); - PerfLogger.log("AbstractCompiler.compile, time spent in JDT process callback: " - + (jdtProcessNanos / 1000000) + "ms"); - cuds = null; - } - - @Override - public void process(CompilationUnitDeclaration unit, int index) { - - long processBeginNanos = System.nanoTime(); - - // The following block of code is a copy of super.process(cud, index), - // with the modification that cud.generateCode is conditionally called - // based on doGenerateBytes - { - this.lookupEnvironment.unitBeingCompleted = unit; - long parseStart = System.currentTimeMillis(); - - this.parser.getMethodBodies(unit); - - long resolveStart = System.currentTimeMillis(); - this.stats.parseTime += resolveStart - parseStart; - - // fault in fields & methods - if (unit.scope != null) { - unit.scope.faultInTypes(); - } - - // verify inherited methods - if (unit.scope != null) { - unit.scope.verifyMethods(lookupEnvironment.methodVerifier()); - } - - // type checking - unit.resolve(); - - long analyzeStart = System.currentTimeMillis(); - this.stats.resolveTime += analyzeStart - resolveStart; - - // flow analysis - unit.analyseCode(); - - long generateStart = System.currentTimeMillis(); - this.stats.analyzeTime += generateStart - analyzeStart; - - // code generation - // code generation - if (doGenerateBytes) { - unit.generateCode(); - } - - // reference info - if (options.produceReferenceInfo && unit.scope != null) { - unit.scope.storeDependencyInfo(); - } - - // finalize problems (suppressWarnings) - unit.finalizeProblems(); - - this.stats.generateTime += System.currentTimeMillis() - generateStart; - - // refresh the total number of units known at this stage - unit.compilationResult.totalUnitsKnown = totalUnits; - - this.lookupEnvironment.unitBeingCompleted = null; - } - - ICompilationUnit cu = unit.compilationResult.compilationUnit; - String loc = String.valueOf(cu.getFileName()); - TreeLogger logger = threadLogger.branch(TreeLogger.SPAM, - "Scanning for additional dependencies: " + loc, null); - - // Examine the cud for magic types. - // - String[] typeNames = doFindAdditionalTypesUsingJsni(logger, unit); - addAdditionalTypes(logger, typeNames); - - typeNames = doFindAdditionalTypesUsingRebinds(logger, unit); - addAdditionalTypes(logger, typeNames); - - typeNames = doFindAdditionalTypesUsingArtificialRescues(logger, unit); - addAdditionalTypes(logger, typeNames); - - doCompilationUnitDeclarationValidation(unit, logger); - - // Optionally remember this cud. - // - if (cuds != null) { - cuds.add(unit); + private static class Sandbox { + + /** + * Adapted to hook the processing of compilation unit declarations so as to + * be able to add additional compilation units based on the results of + * previously-compiled ones. Examples of cases where this is useful include + * classes referenced only from JSNI and <code>GWT.create</code>. + */ + private class CompilerImpl extends Compiler { + + private Set<CompilationUnitDeclaration> cuds; + private long jdtProcessNanos; + + public CompilerImpl(INameEnvironment environment, + IErrorHandlingPolicy policy, CompilerOptions compilerOptions, + ICompilerRequestor requestor, IProblemFactory problemFactory) { + super(environment, policy, compilerOptions, requestor, problemFactory); + } + + @Override + public void compile(ICompilationUnit[] sourceUnits) { + jdtProcessNanos = 0; + super.compile(sourceUnits); + PerfLogger.log("AbstractCompiler.compile, time spent in JDT process callback: " + + (jdtProcessNanos / 1000000) + "ms"); + cuds = null; + } + + @Override + public void process(CompilationUnitDeclaration unit, int index) { + + long processBeginNanos = System.nanoTime(); + + // The following block of code is a copy of super.process(cud, index), + // with the modification that cud.generateCode is conditionally called + // based on doGenerateBytes + { + this.lookupEnvironment.unitBeingCompleted = unit; + long parseStart = System.currentTimeMillis(); + + this.parser.getMethodBodies(unit); + + long resolveStart = System.currentTimeMillis(); + this.stats.parseTime += resolveStart - parseStart; + + // fault in fields & methods + if (unit.scope != null) { + unit.scope.faultInTypes(); + } + + // verify inherited methods + if (unit.scope != null) { + unit.scope.verifyMethods(lookupEnvironment.methodVerifier()); + } + + // type checking + unit.resolve(); + + long analyzeStart = System.currentTimeMillis(); + this.stats.resolveTime += analyzeStart - resolveStart; + + // flow analysis + unit.analyseCode(); + + long generateStart = System.currentTimeMillis(); + this.stats.analyzeTime += generateStart - analyzeStart; + + // code generation + // code generation + if (doGenerateBytes) { + unit.generateCode(); + } + + // reference info + if (options.produceReferenceInfo && unit.scope != null) { + unit.scope.storeDependencyInfo(); + } + + // finalize problems (suppressWarnings) + unit.finalizeProblems(); + + this.stats.generateTime += System.currentTimeMillis() - generateStart; + + // refresh the total number of units known at this stage + unit.compilationResult.totalUnitsKnown = totalUnits; + + this.lookupEnvironment.unitBeingCompleted = null; + } + + ICompilationUnit cu = unit.compilationResult.compilationUnit; + String loc = String.valueOf(cu.getFileName()); + TreeLogger branch = logger.branch(TreeLogger.SPAM, + "Scanning for additional dependencies: " + loc, null); + + // Examine the cud for magic types. + // + String[] typeNames = outer.doFindAdditionalTypesUsingJsni(branch, unit); + addAdditionalTypes(branch, typeNames); + + typeNames = outer.doFindAdditionalTypesUsingRebinds(branch, unit); + addAdditionalTypes(branch, typeNames); + + typeNames = outer.doFindAdditionalTypesUsingArtificialRescues(branch, + unit); + addAdditionalTypes(branch, typeNames); + + // Optionally remember this cud. + // + if (cuds != null) { + cuds.add(unit); + } + + jdtProcessNanos += System.nanoTime() - processBeginNanos; } - jdtProcessNanos += System.nanoTime() - processBeginNanos; - } - - /** - * Helper method for process() that receives the types found by magic. This - * causes the compiler to find the additional type, possibly winding its - * back to ask for the compilation unit from the source oracle. - */ - private void addAdditionalTypes(TreeLogger logger, String[] typeNames) { - for (int i = 0; i < typeNames.length; i++) { - String typeName = typeNames[i]; - final String msg = "Need additional type '" + typeName + "'"; - logger.log(TreeLogger.SPAM, msg, null); - - resolvePossiblyNestedType(typeName); - } - } - - private void compile(ICompilationUnit[] units, - Set<CompilationUnitDeclaration> cuds) { - this.cuds = cuds; - compile(units); + /** + * Helper method for process() that receives the types found by magic. + * This causes the compiler to find the additional type, possibly winding + * its back to ask for the compilation unit from the source oracle. + */ + private void addAdditionalTypes(TreeLogger logger, String[] typeNames) { + for (int i = 0; i < typeNames.length; i++) { + String typeName = typeNames[i]; + final String msg = "Need additional type '" + typeName + "'"; + logger.log(TreeLogger.SPAM, msg, null); + + resolvePossiblyNestedType(typeName); + } + } + + private void compile(ICompilationUnit[] units, + Set<CompilationUnitDeclaration> cuds) { + this.cuds = cuds; + compile(units); + } + + private ReferenceBinding resolvePossiblyNestedType(String typeName) { + return JdtCompiler.resolveType(lookupEnvironment, typeName); + } } - private ReferenceBinding resolvePossiblyNestedType(String typeName) { - return JdtCompiler.resolveType(lookupEnvironment, typeName); - } - } - - private class ICompilerRequestorImpl implements ICompilerRequestor { - - public ICompilerRequestorImpl() { - } - - public void acceptResult(CompilationResult result) { - // Handle compilation errors. - // - IProblem[] errors = result.getErrors(); - - if (errors != null && errors.length > 0) { - // Dump it to disk. - // - String fn = String.valueOf(result.compilationUnit.getFileName()); - String msg = "Errors in '" + fn + "'"; - TreeLogger branch = getLogger().branch(TreeLogger.ERROR, msg, null); - - for (int i = 0; i < errors.length; i++) { - IProblem error = errors[i]; - - // Strip the initial code from each error. - // - msg = error.toString(); - msg = msg.substring(msg.indexOf(' ')); - - // Append 'Line #: msg' to the error message. - // - StringBuffer msgBuf = new StringBuffer(); - int line = error.getSourceLineNumber(); - if (line > 0) { - msgBuf.append("Line "); - msgBuf.append(line); - msgBuf.append(": "); - } - msgBuf.append(msg); - - HelpInfo helpInfo = null; - if (error instanceof GWTProblem) { - GWTProblem gwtProblem = (GWTProblem) error; - helpInfo = gwtProblem.getHelpInfo(); - } - branch.log(TreeLogger.ERROR, msgBuf.toString(), null, helpInfo); + private class ICompilerRequestorImpl implements ICompilerRequestor { + + public ICompilerRequestorImpl() { + } + + public void acceptResult(CompilationResult result) { + // Handle compilation errors. + // + IProblem[] errors = result.getErrors(); + + if (errors != null && errors.length > 0) { + // Dump it to disk. + // + String fn = String.valueOf(result.compilationUnit.getFileName()); + String msg = "Errors in '" + fn + "'"; + TreeLogger branch = logger.branch(TreeLogger.ERROR, msg, null); + + for (int i = 0; i < errors.length; i++) { + IProblem error = errors[i]; + + // Strip the initial code from each error. + // + msg = error.toString(); + msg = msg.substring(msg.indexOf(' ')); + + // Append 'Line #: msg' to the error message. + // + StringBuffer msgBuf = new StringBuffer(); + int line = error.getSourceLineNumber(); + if (line > 0) { + msgBuf.append("Line "); + msgBuf.append(line); + msgBuf.append(": "); + } + msgBuf.append(msg); + + HelpInfo helpInfo = null; + if (error instanceof GWTProblem) { + GWTProblem gwtProblem = (GWTProblem) error; + helpInfo = gwtProblem.getHelpInfo(); + } + branch.log(TreeLogger.ERROR, msgBuf.toString(), null, helpInfo); + } } } - - // Let the subclass do something with this if it wants to. - // - doAcceptResult(result); - } - } - - private class INameEnvironmentImpl implements INameEnvironment { - - public INameEnvironmentImpl() { - } - - public void cleanup() { - // intentionally blank - } - - public NameEnvironmentAnswer findType(char[] type, char[][] pkg) { - return findType(CharOperation.arrayConcat(pkg, type)); - } - - public NameEnvironmentAnswer findType(char[][] compoundTypeName) { - String qname = CharOperation.toString(compoundTypeName); - TreeLogger logger = threadLogger.branch(TreeLogger.SPAM, - "Compiler is asking about '" + qname + "'", null); - - if (isPackage(qname)) { - logger.log(TreeLogger.SPAM, "Found to be a package", null); - return null; - } - - // Didn't find it in the cache, so let's compile from source. - // Strip off the inner types, if any - // - String className = qname; - int pos = qname.indexOf('$'); - if (pos >= 0) { - qname = qname.substring(0, pos); - } - CompilationUnit unit = findCompilationUnit(qname); - if (unit != null) { - logger.log(TreeLogger.SPAM, "Found type in compilation unit: " - + unit.getDisplayLocation()); - ICompilationUnit icu = new CompilationUnitAdapter(unit); - return new NameEnvironmentAnswer(icu, null); - } else { - ClassLoader classLoader = getClassLoader(); - URL resourceURL = classLoader.getResource(className.replace('.', '/') - + ".class"); - if (resourceURL != null) { - /* - * We know that there is a .class file that matches the name that we - * are looking for. However, at least on OSX, this lookup is case - * insensitive so we need to use Class.forName to effectively verify - * the case. - */ - if (isBinaryType(classLoader, className)) { - byte[] classBytes = Util.readURLAsBytes(resourceURL); - ClassFileReader cfr; - try { - cfr = new ClassFileReader(classBytes, null); - return new NameEnvironmentAnswer(cfr, null); - } catch (ClassFormatException e) { - // Ignored. + } + + private class INameEnvironmentImpl implements INameEnvironment { + + public INameEnvironmentImpl() { + } + + public void cleanup() { + // intentionally blank + } + + public NameEnvironmentAnswer findType(char[] type, char[][] pkg) { + return findType(CharOperation.arrayConcat(pkg, type)); + } + + public NameEnvironmentAnswer findType(char[][] compoundTypeName) { + String qname = CharOperation.toString(compoundTypeName); + TreeLogger branch = logger.branch(TreeLogger.SPAM, + "Compiler is asking about '" + qname + "'", null); + + if (isPackage(qname)) { + branch.log(TreeLogger.SPAM, "Found to be a package", null); + return null; + } + + // Didn't find it in the cache, so let's compile from source. + // Strip off the inner types, if any + // + String className = qname; + int pos = qname.indexOf('$'); + if (pos >= 0) { + qname = qname.substring(0, pos); + } + CompilationUnit unit = findCompilationUnit(qname); + if (unit != null) { + branch.log(TreeLogger.SPAM, "Found type in compilation unit: " + + unit.getDisplayLocation()); + ICompilationUnit icu = new CompilationUnitAdapter(unit); + return new NameEnvironmentAnswer(icu, null); + } else { + ClassLoader classLoader = getClassLoader(); + URL resourceURL = classLoader.getResource(className.replace('.', '/') + + ".class"); + if (resourceURL != null) { + /* + * We know that there is a .class file that matches the name that we + * are looking for. However, at least on OSX, this lookup is case + * insensitive so we need to use Class.forName to effectively verify + * the case. + */ + if (isBinaryType(classLoader, className)) { + byte[] classBytes = Util.readURLAsBytes(resourceURL); + ClassFileReader cfr; + try { + cfr = new ClassFileReader(classBytes, null); + return new NameEnvironmentAnswer(cfr, null); + } catch (ClassFormatException e) { + // Ignored. + } } } - } - - logger.log(TreeLogger.SPAM, "Not a known type", null); - return null; - } - } - - public boolean isPackage(char[][] parentPkg, char[] pkg) { - // In special cases where class bytes are asserted from the outside, - // a package can exist that the host doesn't know about. We have to - // do a special check for these cases. - // - final char[] pathChars = CharOperation.concatWith(parentPkg, pkg, '.'); - String packageName = String.valueOf(pathChars); - if (knownPackages.contains(packageName)) { - return true; - } else if (isPackage(packageName) - || isPackage(getClassLoader(), packageName)) { - // Grow our own list to spare calls into the host. + + branch.log(TreeLogger.SPAM, "Not a known type", null); + return null; + } + } + + public boolean isPackage(char[][] parentPkg, char[] pkg) { + // In special cases where class bytes are asserted from the outside, + // a package can exist that the host doesn't know about. We have to + // do a special check for these cases. // - rememberPackage(packageName); - return true; - } else { + final char[] pathChars = CharOperation.concatWith(parentPkg, pkg, '.'); + String packageName = String.valueOf(pathChars); + if (isPackage(packageName)) { + return true; + } else if (isPackage(getClassLoader(), packageName)) { + // Grow our own list to spare calls into the host. + // + rememberPackage(packageName); + return true; + } else { + return false; + } + } + + private ClassLoader getClassLoader() { + return Thread.currentThread().getContextClassLoader(); + } + + private boolean isBinaryType(ClassLoader classLoader, String typeName) { + try { + Class.forName(typeName, false, classLoader); + return true; + } catch (ClassNotFoundException e) { + // Ignored. + } catch (LinkageError e) { + // Ignored. + } + + // Assume that it is not a binary type. return false; } - } - - private ClassLoader getClassLoader() { - return Thread.currentThread().getContextClassLoader(); + + private boolean isPackage(ClassLoader classLoader, String packageName) { + String packageAsPath = packageName.replace('.', '/'); + return classLoader.getResource(packageAsPath) != null; + } + + private boolean isPackage(String packageName) { + return knownPackages.contains(packageName); + } } - private boolean isBinaryType(ClassLoader classLoader, String typeName) { - try { - Class.forName(typeName, false, classLoader); - return true; - } catch (ClassNotFoundException e) { - // Ignored. - } catch (LinkageError e) { - // Ignored. - } - - // Assume that it is not a binary type. - return false; + final CompilerImpl compiler; + final boolean doGenerateBytes; + final Set<String> knownPackages = new HashSet<String>(); + TreeLogger logger = null; + AbstractCompiler outer; + + Sandbox(AbstractCompiler outer, boolean doGenerateBytes) { + this.outer = outer; + this.doGenerateBytes = doGenerateBytes; + rememberPackage(""); + + INameEnvironment env = new INameEnvironmentImpl(); + IErrorHandlingPolicy pol = DefaultErrorHandlingPolicies.proceedWithAllProblems(); + IProblemFactory probFact = new DefaultProblemFactory(Locale.getDefault()); + ICompilerRequestor req = new ICompilerRequestorImpl(); + CompilerOptions options = getCompilerOptions(); + + // This is only needed by TypeOracleBuilder to parse metadata. + options.docCommentSupport = false; + + compiler = new CompilerImpl(env, pol, options, req, probFact); + + // Initialize the packages list. + for (CompilationUnit unit : outer.compilationState.getCompilationUnits()) { + String packageName = Shared.getPackageName(unit.getTypeName()); + rememberPackage(packageName); + } + } + + public void clear() { + outer = null; + logger = null; } - private boolean isPackage(ClassLoader classLoader, String packageName) { - String packageAsPath = packageName.replace('.', '/'); - return classLoader.getResource(packageAsPath) != null; + private CompilationUnit findCompilationUnit(String qname) { + // Build the initial set of compilation units. + Map<String, CompilationUnit> unitMap = outer.compilationState.getCompilationUnitMap(); + CompilationUnit unit = unitMap.get(qname); + while (unit == null) { + int pos = qname.lastIndexOf('.'); + if (pos < 0) { + return null; + } + qname = qname.substring(0, pos); + unit = unitMap.get(qname); + } + return unit; } - private boolean isPackage(String packageName) { - return packages.contains(packageName); + /** + * Causes the compilation service itself to recognize the specified package + * name (and all its parent packages), avoiding a call back into the host. + * This is useful as an optimization, but more importantly, it is useful to + * compile against bytecode that was pre-compiled to which we don't have the + * source. This ability is crucial bridging the gap between user-level and + * "dev" code in hosted mode for classes such as JavaScriptHost and + * ShellJavaScriptHost. + */ + private void rememberPackage(String packageName) { + int i = packageName.lastIndexOf('.'); + if (i != -1) { + // Ensure the parent package is also created. + // + rememberPackage(packageName.substring(0, i)); + } + knownPackages.add(packageName); } } @@ -435,73 +500,34 @@ return options; } - protected final CompilationState compilationState; - - protected final ThreadLocalTreeLoggerProxy threadLogger = new ThreadLocalTreeLoggerProxy(); - - private final CompilerImpl compiler; - - private final boolean doGenerateBytes; - - private final Set<String> knownPackages = new HashSet<String>(); - - private final Set<String> packages = new HashSet<String>(); + private Sandbox sandbox; + protected CompilationState compilationState; protected AbstractCompiler(CompilationState compilationState, boolean doGenerateBytes) { this.compilationState = compilationState; - this.doGenerateBytes = doGenerateBytes; - rememberPackage(""); - - INameEnvironment env = new INameEnvironmentImpl(); - IErrorHandlingPolicy pol = DefaultErrorHandlingPolicies.proceedWithAllProblems(); - IProblemFactory probFact = new DefaultProblemFactory(Locale.getDefault()); - ICompilerRequestor req = new ICompilerRequestorImpl(); - CompilerOptions options = getCompilerOptions(); - - // This is only needed by TypeOracleBuilder to parse metadata. - options.docCommentSupport = false; - - compiler = new CompilerImpl(env, pol, options, req, probFact); + this.sandbox = new Sandbox(this, doGenerateBytes); } protected final CompilationUnitDeclaration[] compile(TreeLogger logger, ICompilationUnit[] units) { - // Initialize the packages list. - for (CompilationUnit unit : compilationState.getCompilationUnits()) { - String packageName = Shared.getPackageName(unit.getTypeName()); - addPackages(packageName); - } // Any additional compilation units that are found to be needed will be // pulled in while procssing compilation units. See CompilerImpl.process(). // - TreeLogger oldLogger = threadLogger.push(logger); + sandbox.logger = logger; try { Set<CompilationUnitDeclaration> cuds = new TreeSet<CompilationUnitDeclaration>( CUD_COMPARATOR); - compiler.compile(units, cuds); + sandbox.compiler.compile(units, cuds); int size = cuds.size(); CompilationUnitDeclaration[] cudArray = new CompilationUnitDeclaration[size]; return cuds.toArray(cudArray); } finally { - threadLogger.pop(oldLogger); + sandbox.clear(); + sandbox = null; } } - - @SuppressWarnings("unused") - // overrider may use unused parameter - protected void doAcceptResult(CompilationResult result) { - // Do nothing by default. - // - } - - @SuppressWarnings("unused") - // overrider may use unused parameter - protected void doCompilationUnitDeclarationValidation( - CompilationUnitDeclaration cud, TreeLogger logger) { - // Do nothing by default. - } @SuppressWarnings("unused") // overrider may use unused parameter @@ -524,61 +550,7 @@ return Empty.STRINGS; } - protected CompilationUnit findCompilationUnit(String qname) { - // Build the initial set of compilation units. - Map<String, CompilationUnit> unitMap = compilationState.getCompilationUnitMap(); - CompilationUnit unit = unitMap.get(qname); - while (unit == null) { - int pos = qname.lastIndexOf('.'); - if (pos < 0) { - return null; - } - qname = qname.substring(0, pos); - unit = unitMap.get(qname); - } - return unit; - } - - protected TreeLogger getLogger() { - return threadLogger; - } - - /** - * Causes the compilation service itself to recognize the specified package - * name (and all its parent packages), avoiding a call back into the host. - * This is useful as an optimization, but more importantly, it is useful to - * compile against bytecode that was pre-compiled to which we don't have the - * source. This ability is crucial bridging the gap between user-level and - * "dev" code in hosted mode for classes such as JavaScriptHost and - * ShellJavaScriptHost. - */ - protected void rememberPackage(String packageName) { - int i = packageName.lastIndexOf('.'); - if (i != -1) { - // Ensure the parent package is also created. - // - rememberPackage(packageName.substring(0, i)); - } - knownPackages.add(packageName); - } - - protected ReferenceBinding resolvePossiblyNestedType(String typeName) { - return compiler.resolvePossiblyNestedType(typeName); - } - - private void addPackages(String packageName) { - if (packages.contains(packageName)) { - return; - } - while (true) { - packages.add(String.valueOf(packageName)); - int pos = packageName.lastIndexOf('.'); - if (pos > 0) { - packageName = packageName.substring(0, pos); - } else { - packages.add(""); - break; - } - } + protected final ReferenceBinding resolvePossiblyNestedType(String typeName) { + return sandbox.compiler.resolvePossiblyNestedType(typeName); } } ======================================= --- /trunk/dev/core/src/com/google/gwt/dev/jdt/WebModeCompilerFrontEnd.java Tue Nov 10 20:42:30 2009 +++ /trunk/dev/core/src/com/google/gwt/dev/jdt/WebModeCompilerFrontEnd.java Wed Nov 11 16:03:56 2009 @@ -63,15 +63,6 @@ this.fragmentLoaderCreator = new FragmentLoaderCreator( rebindPermOracle.getGeneratorContext()); } - - @Override - protected void doCompilationUnitDeclarationValidation( - CompilationUnitDeclaration cud, TreeLogger logger) { - /* - * Anything that makes it here was already checked by AstCompiler while - * building TypeOracle; no need to rerun checks. - */ - } @Override protected String[] doFindAdditionalTypesUsingArtificialRescues( --~--~---------~--~----~------------~-------~--~----~ http://groups.google.com/group/Google-Web-Toolkit-Contributors -~----------~----~----~----~------~----~------~--~---
