Package org.eclipse.jdt.internal.compiler.tool

Source Code of org.eclipse.jdt.internal.compiler.tool.EclipseCompilerImpl

/*******************************************************************************
* Copyright (c) 2007, 2009 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
*     IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.jdt.internal.compiler.tool;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;

import javax.annotation.processing.Processor;
import javax.tools.Diagnostic;
import javax.tools.DiagnosticListener;
import javax.tools.JavaFileManager;
import javax.tools.JavaFileObject;
import javax.tools.StandardJavaFileManager;
import javax.tools.StandardLocation;

import org.eclipse.jdt.core.compiler.CategorizedProblem;
import org.eclipse.jdt.core.compiler.CharOperation;
import org.eclipse.jdt.core.compiler.CompilationProgress;
import org.eclipse.jdt.internal.compiler.ClassFile;
import org.eclipse.jdt.internal.compiler.CompilationResult;
import org.eclipse.jdt.internal.compiler.IErrorHandlingPolicy;
import org.eclipse.jdt.internal.compiler.IProblemFactory;
import org.eclipse.jdt.internal.compiler.batch.CompilationUnit;
import org.eclipse.jdt.internal.compiler.batch.FileSystem;
import org.eclipse.jdt.internal.compiler.batch.Main;
import org.eclipse.jdt.internal.compiler.batch.FileSystem.Classpath;
import org.eclipse.jdt.internal.compiler.problem.AbortCompilationUnit;
import org.eclipse.jdt.internal.compiler.problem.DefaultProblemFactory;
import org.eclipse.jdt.internal.compiler.problem.ProblemSeverities;
import org.eclipse.jdt.internal.compiler.util.Messages;
import org.eclipse.jdt.internal.compiler.util.SuffixConstants;

public class EclipseCompilerImpl extends Main {
  private static final CompilationUnit[] NO_UNITS = new CompilationUnit[0];
  private HashMap<CompilationUnit, JavaFileObject> javaFileObjectMap;
  Iterable<? extends JavaFileObject> compilationUnits;
  public JavaFileManager fileManager;
  protected Processor[] processors;
  public DiagnosticListener<? super JavaFileObject> diagnosticListener;

  public EclipseCompilerImpl(PrintWriter out, PrintWriter err, boolean systemExitWhenFinished) {
    super(out, err, systemExitWhenFinished, null/*options*/, null/*progress*/);
  }

  public boolean call() {
    try {
      if (this.proceed) {
        this.globalProblemsCount = 0;
        this.globalErrorsCount = 0;
        this.globalWarningsCount = 0;
        this.globalTasksCount = 0;
        this.exportedClassFilesCounter = 0;
        // request compilation
        performCompilation();
      }
    } catch(IllegalArgumentException e) {
      this.logger.logException(e);
      if (this.systemExitWhenFinished) {
        cleanup();
        System.exit(-1);
      }
      return false;
    } catch (RuntimeException e) { // internal compiler failure
      this.logger.logException(e);
      return false;
    } finally {
      cleanup();
    }
    if (this.globalErrorsCount == 0)
      return true;
    return false;
  }

  private void cleanup() {
    this.logger.flush();
    this.logger.close();
    this.processors = null;
    try {
      if (this.fileManager != null) {
        this.fileManager.flush();
      }
    } catch (IOException e) {
      // ignore
    }
  }

  @Override
  public CompilationUnit[] getCompilationUnits() {
    if (this.compilationUnits == null) return EclipseCompilerImpl.NO_UNITS;
    ArrayList<CompilationUnit> units = new ArrayList<CompilationUnit>();
    for (final JavaFileObject javaFileObject : this.compilationUnits) {
      if (javaFileObject.getKind() != JavaFileObject.Kind.SOURCE) {
        throw new IllegalArgumentException();
      }
      String name = javaFileObject.getName();
      name = name.replace('\\', '/');
      CompilationUnit compilationUnit = new CompilationUnit(null,
        name,
        null) {

        @Override
        public char[] getContents() {
          try {
            return javaFileObject.getCharContent(true).toString().toCharArray();
          } catch(IOException e) {
            e.printStackTrace();
            throw new AbortCompilationUnit(null, e, null);
          }
        }
      };
      units.add(compilationUnit);
      this.javaFileObjectMap.put(compilationUnit, javaFileObject);
    }
    CompilationUnit[] result = new CompilationUnit[units.size()];
    units.toArray(result);
    return result;
  }
  /*
   *  Low-level API performing the actual compilation
   */
  @Override
  public IErrorHandlingPolicy getHandlingPolicy() {
    // passes the initial set of files to the batch oracle (to avoid finding more than once the same units when case insensitive match)
    return new IErrorHandlingPolicy() {
      public boolean proceedOnErrors() {
        return false; // stop if there are some errors
      }
      public boolean stopOnFirstError() {
        return false;
      }
    };
  }

  @Override
  public IProblemFactory getProblemFactory() {
    return new DefaultProblemFactory() {
      @Override
      public CategorizedProblem createProblem(
          final char[] originatingFileName,
          final int problemId,
          final String[] problemArguments,
          final String[] messageArguments,
          final int severity,
          final int startPosition,
          final int endPosition,
          final int lineNumber,
          final int columnNumber) {

        DiagnosticListener<? super JavaFileObject> diagListener = EclipseCompilerImpl.this.diagnosticListener;
        if (diagListener != null) {
          diagListener.report(new Diagnostic<JavaFileObject>() {
            public String getCode() {
              return Integer.toString(problemId);
            }
            public long getColumnNumber() {
              return columnNumber;
            }
            public long getEndPosition() {
              return endPosition;
            }
            public Kind getKind() {
              if ((severity & ProblemSeverities.Error) != 0) {
                return Diagnostic.Kind.ERROR;
              }
              if ((severity & ProblemSeverities.Optional) != 0) {
                return Diagnostic.Kind.WARNING;
              }
              if ((severity & ProblemSeverities.Warning) != 0) {
                return Diagnostic.Kind.MANDATORY_WARNING;
              }
              return Diagnostic.Kind.OTHER;
            }
            public long getLineNumber() {
              return lineNumber;
            }
            public String getMessage(Locale locale) {
              setLocale(locale);
              return getLocalizedMessage(problemId, problemArguments);
            }
            public long getPosition() {
              return startPosition;
            }
            public JavaFileObject getSource() {
              try {
                if (EclipseCompilerImpl.this.fileManager.hasLocation(StandardLocation.SOURCE_PATH)) {
                  return EclipseCompilerImpl.this.fileManager.getJavaFileForInput(
                      StandardLocation.SOURCE_PATH,
                      new String(originatingFileName),
                      JavaFileObject.Kind.SOURCE);
                }
              } catch (IOException e) {
                // ignore
              }
              return null;
            }
            public long getStartPosition() {
              return startPosition;
            }
          });
        }
        return super.createProblem(originatingFileName, problemId, problemArguments, messageArguments, severity, startPosition, endPosition, lineNumber, columnNumber);
      }
    };
  }

  @Override
  @SuppressWarnings("unchecked")
  protected void initialize(PrintWriter outWriter, PrintWriter errWriter, boolean systemExit, Map customDefaultOptions, CompilationProgress compilationProgress) {
    super.initialize(outWriter, errWriter, systemExit, customDefaultOptions, compilationProgress);
    this.javaFileObjectMap = new HashMap<CompilationUnit, JavaFileObject>();
  }

  @Override
  protected void initializeAnnotationProcessorManager() {
    super.initializeAnnotationProcessorManager();
    if (this.batchCompiler.annotationProcessorManager != null && this.processors != null) {
      this.batchCompiler.annotationProcessorManager.setProcessors(this.processors);
    } else if (this.processors != null) {
      throw new UnsupportedOperationException("Cannot handle annotation processing"); //$NON-NLS-1$
    }
  }

  // Dump classfiles onto disk for all compilation units that where successful
  // and do not carry a -d none spec, either directly or inherited from Main.
  @Override
  public void outputClassFiles(CompilationResult unitResult) {
    if (!((unitResult == null) || (unitResult.hasErrors() && !this.proceedOnError))) {
      ClassFile[] classFiles = unitResult.getClassFiles();
      boolean generateClasspathStructure = this.fileManager.hasLocation(StandardLocation.CLASS_OUTPUT);
      String currentDestinationPath = this.destinationPath;
      File outputLocation = null;
      if (currentDestinationPath != null) {
        outputLocation = new File(currentDestinationPath);
        outputLocation.mkdirs();
      }
      for (int i = 0, fileCount = classFiles.length; i < fileCount; i++) {
        // retrieve the key and the corresponding classfile
        ClassFile classFile = classFiles[i];
        char[] filename = classFile.fileName();
        int length = filename.length;
        char[] relativeName = new char[length + 6];
        System.arraycopy(filename, 0, relativeName, 0, length);
        System.arraycopy(SuffixConstants.SUFFIX_class, 0, relativeName, length, 6);
        CharOperation.replace(relativeName, '/', File.separatorChar);
        String relativeStringName = new String(relativeName);
        if (this.compilerOptions.verbose) {
          EclipseCompilerImpl.this.out.println(
            Messages.bind(
              Messages.compilation_write,
              new String[] {
                String.valueOf(this.exportedClassFilesCounter+1),
                relativeStringName
              }));
        }
        try {
          JavaFileObject javaFileForOutput =
          this.fileManager.getJavaFileForOutput(
              StandardLocation.CLASS_OUTPUT,
              new String(filename),
              JavaFileObject.Kind.CLASS,
              this.javaFileObjectMap.get(unitResult.compilationUnit));

          if (generateClasspathStructure) {
            if (currentDestinationPath != null) {
              int index = CharOperation.lastIndexOf(File.separatorChar, relativeName);
              if (index != -1) {
                File currentFolder = new File(currentDestinationPath, relativeStringName.substring(0, index));
                currentFolder.mkdirs();
              }
            } else {
              // create the subfolfers is necessary
              // need a way to retrieve the folders to create
              String path = javaFileForOutput.toUri().getPath();
              int index = path.lastIndexOf('/');
              if (index != -1) {
                File file = new File(path.substring(0, index));
                file.mkdirs();
              }
            }
          }

          OutputStream openOutputStream = javaFileForOutput.openOutputStream();
          BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(openOutputStream);
          bufferedOutputStream.write(classFile.header, 0, classFile.headerOffset);
          bufferedOutputStream.write(classFile.contents, 0, classFile.contentsOffset);
          bufferedOutputStream.flush();
          bufferedOutputStream.close();
        } catch (IOException e) {
          this.logger.logNoClassFileCreated(currentDestinationPath, relativeStringName, e);
        }
        this.logger.logClassFile(
          generateClasspathStructure,
          currentDestinationPath,
          relativeStringName);
        this.exportedClassFilesCounter++;
      }
      this.batchCompiler.lookupEnvironment.releaseClassFiles(classFiles);
    }
  }

  @Override
  @SuppressWarnings("unchecked")
  protected void setPaths(ArrayList bootclasspaths,
      String sourcepathClasspathArg,
      ArrayList sourcepathClasspaths,
      ArrayList classpaths,
      ArrayList extdirsClasspaths,
      ArrayList endorsedDirClasspaths,
      String customEncoding) {

    ArrayList<FileSystem.Classpath> fileSystemClasspaths = new ArrayList<FileSystem.Classpath>();
    EclipseFileManager javaFileManager = null;
    StandardJavaFileManager standardJavaFileManager = null;
    if (this.fileManager instanceof EclipseFileManager) {
      javaFileManager = (EclipseFileManager) this.fileManager;
    }
    if (this.fileManager instanceof StandardJavaFileManager) {
      standardJavaFileManager = (StandardJavaFileManager) this.fileManager;
    }

    if (javaFileManager != null) {
      if ((javaFileManager.flags & EclipseFileManager.HAS_ENDORSED_DIRS) == 0
          && (javaFileManager.flags & EclipseFileManager.HAS_BOOTCLASSPATH) != 0) {
        fileSystemClasspaths.addAll(this.handleEndorseddirs(null));
      }
    }
    Iterable<? extends File> location = null;
    if (standardJavaFileManager != null) {
      location = standardJavaFileManager.getLocation(StandardLocation.PLATFORM_CLASS_PATH);
    }
    if (location != null) {
      for (File file : location) {
        Classpath classpath = FileSystem.getClasspath(
          file.getAbsolutePath(),
          null,
          null);
        if (classpath != null) {
          fileSystemClasspaths.add(classpath);
        }
      }
    }
    if (javaFileManager != null) {
      if ((javaFileManager.flags & EclipseFileManager.HAS_EXT_DIRS) == 0
          && (javaFileManager.flags & EclipseFileManager.HAS_BOOTCLASSPATH) != 0) {
        fileSystemClasspaths.addAll(this.handleExtdirs(null));
      }
    }
    if (standardJavaFileManager != null) {
      location = standardJavaFileManager.getLocation(StandardLocation.SOURCE_PATH);
    } else {
      location = null;
    }
    if (location != null) {
      for (File file : location) {
        Classpath classpath = FileSystem.getClasspath(
            file.getAbsolutePath(),
            null,
            null);
        if (classpath != null) {
          fileSystemClasspaths.add(classpath);
        }
      }
    }
    if (standardJavaFileManager != null) {
      location = standardJavaFileManager.getLocation(StandardLocation.CLASS_PATH);
    } else {
      location = null;
    }
    if (location != null) {
      for (File file : location) {
        Classpath classpath = FileSystem.getClasspath(
          file.getAbsolutePath(),
          null,
          null);
        if (classpath != null) {
          fileSystemClasspaths.add(classpath);
        }
      }
    }
    if (this.checkedClasspaths == null) {
      fileSystemClasspaths.addAll(this.handleBootclasspath(null, null));
      fileSystemClasspaths.addAll(this.handleClasspath(null, null));
    }
    fileSystemClasspaths = FileSystem.ClasspathNormalizer.normalize(fileSystemClasspaths);
    final int size = fileSystemClasspaths.size();
    if (size != 0) {
      this.checkedClasspaths = new FileSystem.Classpath[size];
      int i = 0;
      for (FileSystem.Classpath classpath : fileSystemClasspaths) {
        this.checkedClasspaths[i++] = classpath;
      }
    }
  }
}
TOP

Related Classes of org.eclipse.jdt.internal.compiler.tool.EclipseCompilerImpl

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.