123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259 |
- /*******************************************************************************
- * Copyright (c) 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v 2.0
- * which accompanies this distribution, and is available at
- * https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.txt
- *
- * Contributors:
- * IBM Corporation - initial API and implementation
- *******************************************************************************/
- package org.aspectj.ajdt.internal.compiler;
-
- import java.util.Iterator;
- import java.util.Map;
-
- import org.aspectj.asm.internal.CharOperation;
- import org.aspectj.bridge.IMessage;
- import org.aspectj.bridge.IProgressListener;
- import org.aspectj.bridge.MessageUtil;
- import org.aspectj.org.eclipse.jdt.internal.compiler.ClassFile;
- import org.aspectj.org.eclipse.jdt.internal.compiler.problem.AbortCompilation;
- import org.aspectj.weaver.IClassFileProvider;
- import org.aspectj.weaver.IUnwovenClassFile;
- import org.aspectj.weaver.IWeaveRequestor;
- import org.eclipse.core.runtime.OperationCanceledException;
-
- /**
- * @author colyer This class provides the weaver with a source of class files to weave (via the iterator and IClassFileProvider
- * interfaces). It receives results back from the weaver via the IWeaveRequestor interface.
- */
- public class WeaverAdapter implements IClassFileProvider, IWeaveRequestor, Iterator {
-
- private final AbstractCompilerAdapter compilerAdapter;
- private Iterator<InterimCompilationResult> resultIterator;
- private int classFileIndex = 0;
- private InterimCompilationResult nowProcessing;
- private InterimCompilationResult lastReturnedResult;
- private final WeaverMessageHandler weaverMessageHandler;
- private final IProgressListener progressListener;
- private boolean finalPhase = false;
- private int localIteratorCounter;
-
- // Fields related to progress monitoring
- private int progressMaxTypes;
- private String progressPhasePrefix;
- private double fromPercent;
- private final double toPercent = 100.0;
- private int progressCompletionCount;
-
- public WeaverAdapter(AbstractCompilerAdapter forCompiler, WeaverMessageHandler weaverMessageHandler,
- IProgressListener progressListener) {
- this.compilerAdapter = forCompiler;
- this.weaverMessageHandler = weaverMessageHandler;
- this.progressListener = progressListener;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see org.aspectj.weaver.IClassFileProvider#getClassFileIterator()
- */
- public Iterator getClassFileIterator() {
- classFileIndex = 0;
- localIteratorCounter = 0;
- nowProcessing = null;
- lastReturnedResult = null;
- resultIterator = compilerAdapter.getResultsPendingWeave().iterator();
- return this;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see org.aspectj.weaver.IClassFileProvider#getRequestor()
- */
- public IWeaveRequestor getRequestor() {
- return this;
- }
-
- public boolean isApplyAtAspectJMungersOnly() {
- return false;
- }
-
- // Iteration
- // ================================================================
-
- /*
- * (non-Javadoc)
- *
- * @see java.util.Iterator#hasNext()
- */
- public boolean hasNext() {
- if (nowProcessing == null) {
- if (!resultIterator.hasNext())
- return false;
- nowProcessing = (InterimCompilationResult) resultIterator.next();
- classFileIndex = 0;
- }
- while (nowProcessing.unwovenClassFiles().length == 0) {
- if (!resultIterator.hasNext())
- return false;
- nowProcessing = (InterimCompilationResult) resultIterator.next();
- }
- if (classFileIndex < nowProcessing.unwovenClassFiles().length) {
- return true;
- } else {
- classFileIndex = 0;
- if (!resultIterator.hasNext())
- return false;
- nowProcessing = (InterimCompilationResult) resultIterator.next();
- while (nowProcessing.unwovenClassFiles().length == 0) {
- if (!resultIterator.hasNext())
- return false;
- nowProcessing = (InterimCompilationResult) resultIterator.next();
- }
- }
- return true;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see java.util.Iterator#next()
- */
- public Object next() {
- if (!hasNext())
- return null; // sets up indices correctly
- if (finalPhase) {
- if ((lastReturnedResult != null) && (lastReturnedResult != nowProcessing)) {
- // we're done with the lastReturnedResult
- finishedWith(lastReturnedResult);
- }
- }
- localIteratorCounter++;
- lastReturnedResult = nowProcessing;
- weaverMessageHandler.setCurrentResult(nowProcessing.result());
- // weaverMessageHandler.handleMessage(new Message("weaving " + nowProcessing.fileName(),IMessage.INFO, null, null));
- return nowProcessing.unwovenClassFiles()[classFileIndex++];
- }
-
- /*
- * (non-Javadoc)
- *
- * @see java.util.Iterator#remove()
- */
- public void remove() {
- throw new UnsupportedOperationException();
- }
-
- // IWeaveRequestor
- // =====================================================================================
-
- // weave phases as indicated by bcelWeaver...
- public void processingReweavableState() {
-
- // progress reporting logic
- fromPercent = 50.0; // Assume weaving takes 50% of the progress bar...
- // recordProgress("processing reweavable state");
- }
-
- public void addingTypeMungers() {
-
- // progress reporting logic
- // At this point we have completed one iteration through all the classes/aspects
- // we'll be dealing with, so let us remember this max value for localIteratorCounter
- // (for accurate progress reporting)
- // recordProgress("adding type mungers");
- progressMaxTypes = localIteratorCounter;
- }
-
- public void weavingAspects() {
-
- // progress reporting logic
- progressPhasePrefix = "woven aspect ";
- progressCompletionCount = 0; // Start counting from *now*
- }
-
- public void weavingClasses() {
- finalPhase = true;
-
- // progress reporting logic
- progressPhasePrefix = "woven class ";
- }
-
- public void weaveCompleted() {
- if ((lastReturnedResult != null) && (!lastReturnedResult.result().hasBeenAccepted)) {
- finishedWith(lastReturnedResult);
- }
- lastReturnedResult = null;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see org.aspectj.weaver.IWeaveRequestor#acceptResult(org.aspectj.weaver.bcel.UnwovenClassFile)
- */
- public void acceptResult(IUnwovenClassFile result) {
- char[] key = result.getClassNameAsChars();
- removeFromMap(lastReturnedResult.result().compiledTypes, key);
- AjClassFile ajcf = new AjClassFile(key, result.getBytes());
- lastReturnedResult.result().record(ajcf.fileName(), ajcf);
- if (!weaverMessageHandler.isIgnoring(IMessage.INFO) || progressListener != null) {
- StringBuilder msg = new StringBuilder();
- msg.append(progressPhasePrefix).append(result.getClassName()).append(" (from ").append(nowProcessing.fileName())
- .append(")");
- weaverMessageHandler.handleMessage(MessageUtil.info(msg.toString()));
- if (progressListener != null) {
- progressCompletionCount++;
-
- // Smoothly take progress from 'fromPercent' to 'toPercent'
- recordProgress(fromPercent + ((progressCompletionCount / (double) progressMaxTypes) * (toPercent - fromPercent)),
- msg.toString());
- // progressPhasePrefix+result.getClassName()+" (from "+nowProcessing.fileName()+")");
-
- if (progressListener.isCancelledRequested()) {
- throw new AbortCompilation(true, new OperationCanceledException("Weaving cancelled as requested"));
- }
- }
- }
- }
-
- // helpers...
- // =================================================================
-
- private void finishedWith(InterimCompilationResult result) {
- compilerAdapter.acceptResult(result.result());
- }
-
- private boolean removeFromMap(Map<char[], ClassFile> aMap, char[] key) {
- // jdt uses char[] as a key in the hashtable, which is not very useful as equality is based on being
- // the same array, not having the same content.
- // String skey = new String(key);
- // OPTIMIZE what is this code for?
- if (aMap.remove(key) != null) {
- return true;
- }
- char[] victim = null;
- for (Object o : aMap.keySet()) {
- char[] thisKey = (char[]) o;
- if (CharOperation.equals(thisKey, key)) {
- // if (skey.equals(new String(thisKey))) {
- victim = thisKey;
- break;
- }
- }
- if (victim != null) {
- aMap.remove(victim);
- return true;
- }
- return false;
- }
-
- private void recordProgress(double percentage, String message) {
- if (progressListener != null) {
- progressListener.setProgress(percentage / 100);
- progressListener.setText(message);
- }
- }
- }
|