Package com.google.gwt.dev.javac

Source Code of com.google.gwt.dev.javac.JdtCompiler$ICompilerRequestorImpl

/*
* Copyright 2008 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.javac;

import com.google.gwt.dev.javac.impl.Shared;
import com.google.gwt.dev.util.PerfLogger;
import com.google.gwt.util.tools.Utility;

import org.eclipse.jdt.core.compiler.CharOperation;
import org.eclipse.jdt.internal.compiler.CompilationResult;
import org.eclipse.jdt.internal.compiler.Compiler;
import org.eclipse.jdt.internal.compiler.DefaultErrorHandlingPolicies;
import org.eclipse.jdt.internal.compiler.ICompilerRequestor;
import org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration;
import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
import org.eclipse.jdt.internal.compiler.classfmt.ClassFileReader;
import org.eclipse.jdt.internal.compiler.classfmt.ClassFormatException;
import org.eclipse.jdt.internal.compiler.env.ICompilationUnit;
import org.eclipse.jdt.internal.compiler.env.INameEnvironment;
import org.eclipse.jdt.internal.compiler.env.NameEnvironmentAnswer;
import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
import org.eclipse.jdt.internal.compiler.problem.DefaultProblemFactory;

import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;

/**
* Manages the process of compiling {@link CompilationUnit}s.
*/
public class JdtCompiler {

  /**
   * Adapts a {@link CompilationUnit} for a JDT compile.
   */
  public static class CompilationUnitAdapter implements ICompilationUnit {

    private final CompilationUnit unit;

    public CompilationUnitAdapter(CompilationUnit unit) {
      this.unit = unit;
    }

    public char[] getContents() {
      return unit.getSource().toCharArray();
    }

    public char[] getFileName() {
      return unit.getDisplayLocation().toCharArray();
    }

    public char[] getMainTypeName() {
      return Shared.getShortName(unit.getTypeName()).toCharArray();
    }

    public char[][] getPackageName() {
      String packageName = Shared.getPackageName(unit.getTypeName());
      return CharOperation.splitOn('.', packageName.toCharArray());
    }

    public CompilationUnit getUnit() {
      return unit;
    }

    @Override
    public String toString() {
      return unit.toString();
    }
  }
  private class CompilerImpl extends Compiler {

    public CompilerImpl() {
      super(new INameEnvironmentImpl(),
          DefaultErrorHandlingPolicies.proceedWithAllProblems(),
          getCompilerOptions(), new ICompilerRequestorImpl(),
          new DefaultProblemFactory(Locale.getDefault()));
    }

    @Override
    public void process(CompilationUnitDeclaration cud, int i) {
      super.process(cud, i);
      ICompilationUnit icu = cud.compilationResult().compilationUnit;
      CompilationUnitAdapter adapter = (CompilationUnitAdapter) icu;
      CompilationUnit unit = adapter.getUnit();
      unit.setCompiled(cud);
      if (!cud.compilationResult().hasErrors()) {
        recordBinaryTypes(unit.getCompiledClasses());
      }
    }
  }

  /**
   * Hook point to accept results.
   */
  private static class ICompilerRequestorImpl implements ICompilerRequestor {
    public void acceptResult(CompilationResult result) {
    }
  }

  /**
   * How JDT receives files from the environment.
   */
  private class INameEnvironmentImpl implements INameEnvironment {
    public void cleanup() {
    }

    public NameEnvironmentAnswer findType(char[] type, char[][] pkg) {
      return findType(CharOperation.arrayConcat(pkg, type));
    }

    public NameEnvironmentAnswer findType(char[][] compoundTypeName) {
      char[] binaryNameChars = CharOperation.concatWith(compoundTypeName, '/');
      String binaryName = String.valueOf(binaryNameChars);
      CompiledClass compiledClass = binaryTypes.get(binaryName);
      if (compiledClass != null) {
        return compiledClass.getNameEnvironmentAnswer();
      }
      if (isPackage(binaryName)) {
        return null;
      }
      try {
        URL resource = getClassLoader().getResource(binaryName + ".class");
        if (resource != null) {
          InputStream openStream = resource.openStream();
          try {
            ClassFileReader cfr = ClassFileReader.read(openStream,
                resource.toExternalForm(), true);
            return new NameEnvironmentAnswer(cfr, null);
          } finally {
            Utility.close(openStream);
          }
        }
      } catch (ClassFormatException e) {
      } catch (IOException e) {
      }
      return null;
    }

    public boolean isPackage(char[][] parentPkg, char[] pkg) {
      char[] pathChars = CharOperation.concatWith(parentPkg, pkg, '/');
      String packageName = String.valueOf(pathChars);
      return isPackage(packageName);
    }

    private ClassLoader getClassLoader() {
      return Thread.currentThread().getContextClassLoader();
    }

    private boolean isPackage(String slashedPackageName) {
      // Include class loader check for binary-only annotations.
      if (packages.contains(slashedPackageName)) {
        return true;
      }
      if (notPackages.contains(slashedPackageName)) {
        return false;
      }
      String resourceName = slashedPackageName + '/';
      if (getClassLoader().getResource(resourceName) != null) {
        addPackages(slashedPackageName);
        return true;
      } else {
        notPackages.add(slashedPackageName);
        return false;
      }
    }
  }

  /**
   * Compiles the given set of units. The units will be internally modified to
   * reflect the results of compilation.
   */
  public static boolean compile(Collection<CompilationUnit> units) {
    return new JdtCompiler().doCompile(units);
  }

  public static CompilerOptions getCompilerOptions() {
    CompilerOptions options = new CompilerOptions();
    options.complianceLevel = options.sourceLevel = options.targetJDK = ClassFileConstants.JDK1_6;

    // Generate debug info for debugging the output.
    options.produceDebugAttributes = ClassFileConstants.ATTR_VARS
        | ClassFileConstants.ATTR_LINES | ClassFileConstants.ATTR_SOURCE;
    // Tricks like "boolean stopHere = true;" depend on this setting.
    options.preserveAllLocalVariables = true;

    // Turn off all warnings, saves some memory / speed.
    options.reportUnusedDeclaredThrownExceptionIncludeDocCommentReference = false;
    options.reportUnusedDeclaredThrownExceptionExemptExceptionAndThrowable = false;
    options.warningThreshold = 0;
    options.inlineJsrBytecode = true;
    return options;
  }

  /**
   * Maps dotted binary names to compiled classes.
   */
  private final Map<String, CompiledClass> binaryTypes = new HashMap<String, CompiledClass>();

  private final Set<String> notPackages = new HashSet<String>();

  private final Set<String> packages = new HashSet<String>();

  /**
   * Not externally instantiable.
   */
  public JdtCompiler() {
  }

  public boolean doCompile(Collection<CompilationUnit> units) {
    List<ICompilationUnit> icus = new ArrayList<ICompilationUnit>();
    for (CompilationUnit unit : units) {
      String packageName = Shared.getPackageName(unit.getTypeName()).replace(
          '.', '/');
      addPackages(packageName);
      Set<CompiledClass> compiledClasses = unit.getCompiledClasses();
      if (compiledClasses == null) {
        icus.add(new CompilationUnitAdapter(unit));
      } else {
        recordBinaryTypes(compiledClasses);
      }
    }
    if (icus.isEmpty()) {
      return false;
    }

    PerfLogger.start("JdtCompiler.compile");
    new CompilerImpl().compile(icus.toArray(new ICompilationUnit[icus.size()]));
    PerfLogger.end();
    return true;
  }

  private void addPackages(String slashedPackageName) {
    while (packages.add(slashedPackageName)) {
      int pos = slashedPackageName.lastIndexOf('/');
      if (pos > 0) {
        slashedPackageName = slashedPackageName.substring(0, pos);
      } else {
        packages.add("");
        break;
      }
    }
  }

  private void recordBinaryTypes(Set<CompiledClass> compiledClasses) {
    for (CompiledClass compiledClass : compiledClasses) {
      binaryTypes.put(compiledClass.getInternalName(), compiledClass);
    }
  }

}
TOP

Related Classes of com.google.gwt.dev.javac.JdtCompiler$ICompilerRequestorImpl

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.