I don't think this will work, but backing it up anyway.
diff --git a/org.eclipse.ajdt.core/src/org/eclipse/ajdt/core/codeconversion/AspectsConvertingParser.java b/org.eclipse.ajdt.core/src/org/eclipse/ajdt/core/codeconversion/AspectsConvertingParser.java index c58d6fe..1f5e456 100644 --- a/org.eclipse.ajdt.core/src/org/eclipse/ajdt/core/codeconversion/AspectsConvertingParser.java +++ b/org.eclipse.ajdt.core/src/org/eclipse/ajdt/core/codeconversion/AspectsConvertingParser.java
@@ -976,28 +976,40 @@ // position before the inserted area public static int translatePositionToBeforeChanges(int posAfter, ArrayList replacements) { - Replacement ins; - int offset = 0, i; + return translatePositionToBeforeChanges(posAfter, replacements, false); + } + + // as above, but if the position doesn't exist in the original, + // return -1 + public static int translatePositionToBeforeChanges(int posAfter, + ArrayList replacements, boolean faultOnNonExistantPosition) { + Replacement ins; + int offset = 0, i; - for (i = 0; i < replacements.size(); i++) { - ins = (Replacement) replacements.get(i); - if (ins.posAfter > posAfter) - break; - offset += ins.lengthAdded; - } - if (i > 0) { - ins = (Replacement) replacements.get(i - 1); - if (ins.posAfter + ins.text.length > posAfter) { - //diff must be > 0 - int diff = posAfter - ins.posAfter; - if (diff > ins.length) - //we are in inserted area -> return pos directly before - // that area - offset += diff - ins.length; - } - } + for (i = 0; i < replacements.size(); i++) { + ins = (Replacement) replacements.get(i); + if (ins.posAfter > posAfter) + break; + offset += ins.lengthAdded; + } + if (i > 0) { + ins = (Replacement) replacements.get(i - 1); + if (ins.posAfter + ins.text.length > posAfter) { + //diff must be > 0 + int diff = posAfter - ins.posAfter; + if (diff > ins.length) { + // we are in inserted area + if (faultOnNonExistantPosition) { + return -1; + } else { + // return pos directly before that area + offset += diff - ins.length; + } + } + } + } - return posAfter - offset; + return posAfter - offset; } //translates a position from before to after changes
diff --git a/org.eclipse.ajdt.core/src/org/eclipse/ajdt/core/codeconversion/JavaCompatibleBuffer.java b/org.eclipse.ajdt.core/src/org/eclipse/ajdt/core/codeconversion/JavaCompatibleBuffer.java index 72dbe47..08209eb 100644 --- a/org.eclipse.ajdt.core/src/org/eclipse/ajdt/core/codeconversion/JavaCompatibleBuffer.java +++ b/org.eclipse.ajdt.core/src/org/eclipse/ajdt/core/codeconversion/JavaCompatibleBuffer.java
@@ -20,6 +20,10 @@ import org.eclipse.jdt.core.ICompilationUnit; import org.eclipse.jdt.core.IOpenable; import org.eclipse.jdt.core.JavaModelException; +import org.eclipse.jdt.internal.core.DocumentAdapter; +import org.eclipse.jface.text.BadLocationException; +import org.eclipse.jface.text.IDocument; +import org.eclipse.jface.text.IRegion; /** * This Wrapper forwards changes to the real buffer, but @@ -162,8 +166,9 @@ this.ensureUpToDate(); return AspectsConvertingParser.translatePositionToAfterChanges(pos, insertionTable); } + - /* (non-Javadoc) + /* (non-Javadoc) * @see org.eclipse.jdt.core.IBufferChangedListener#bufferChanged(org.eclipse.jdt.core.BufferChangedEvent) */ public void bufferChanged(BufferChangedEvent event) { @@ -180,4 +185,8 @@ this.conversionOptions = conversionOptions; upToDate = false; } + + public IBuffer getRealBuffer() { + return realBuffer; + } }
diff --git a/org.eclipse.ajdt.core/src/org/eclipse/ajdt/core/javaelements/AJCompilationUnit.java b/org.eclipse.ajdt.core/src/org/eclipse/ajdt/core/javaelements/AJCompilationUnit.java index 04c2eb1..def2cba 100755 --- a/org.eclipse.ajdt.core/src/org/eclipse/ajdt/core/javaelements/AJCompilationUnit.java +++ b/org.eclipse.ajdt.core/src/org/eclipse/ajdt/core/javaelements/AJCompilationUnit.java
@@ -15,14 +15,17 @@ import java.lang.reflect.InvocationTargetException; import java.util.ArrayList; import java.util.HashMap; +import java.util.List; import java.util.Map; import org.aspectj.asm.IProgramElement; import org.eclipse.ajdt.core.AJLog; import org.eclipse.ajdt.core.AspectJPlugin; +import org.eclipse.ajdt.core.codeconversion.AspectsConvertingParser; import org.eclipse.ajdt.core.codeconversion.ConversionOptions; import org.eclipse.ajdt.core.codeconversion.ITDAwareCancelableNameEnvironment; import org.eclipse.ajdt.core.codeconversion.JavaCompatibleBuffer; +import org.eclipse.ajdt.core.codeconversion.AspectsConvertingParser.Replacement; import org.eclipse.ajdt.core.parserbridge.AJCompilationUnitStructureRequestor; import org.eclipse.ajdt.core.parserbridge.AJSourceElementParser; import org.eclipse.ajdt.core.reconcile.AJReconcileWorkingCopyOperation; @@ -69,6 +72,11 @@ import org.eclipse.jdt.internal.core.SearchableEnvironment; import org.eclipse.jdt.internal.core.SourceType; import org.eclipse.jdt.internal.core.util.MementoTokenizer; +import org.eclipse.jdt.internal.core.util.SimpleDocument; +import org.eclipse.jface.text.BadLocationException; +import org.eclipse.jface.text.Document; +import org.eclipse.jface.text.IDocument; +import org.eclipse.jface.text.IRegion; /** @@ -85,7 +93,67 @@ */ public class AJCompilationUnit extends CompilationUnit{ - int originalContentMode = 0; + /** + * Cloned Unit for doing reconciling. + * Always want to use CODE_COMPLETE style of conversion + * @author andrew + * + */ + public final class ClonedAJCU extends AJCompilationUnit { + private char[] cachedFakeContents; + private IDocument cachedOrigDocument; + private ArrayList/*Replacement*/ replacements; + + public ClonedAJCU(PackageFragment fragment, String elementName, + WorkingCopyOwner workingCopyOwner) { + super(fragment, elementName, workingCopyOwner); + } + + public char[] getContents() { + if (this.cachedFakeContents == null) { + AJCompilationUnit.this.requestOriginalContentMode(); + char[] cachedOrigContents = AJCompilationUnit.this.getContents(); + AJCompilationUnit.this.discardOriginalContentMode(); + cachedOrigDocument = new Document(new String(cachedOrigContents)); + + AspectsConvertingParser transformer = new AspectsConvertingParser(cachedOrigContents); + transformer.setUnit(AJCompilationUnit.this); + replacements = transformer.convert(ConversionOptions.CODE_COMPLETION); + this.cachedFakeContents = transformer.content; + + } + return this.cachedFakeContents; + } + + public CompilationUnit originalFromClone() { + return AJCompilationUnit.this; + } + + public int translatePositionToReal(int pos){ + return AspectsConvertingParser.translatePositionToBeforeChanges(pos, replacements, true); + } + + public int getLineOfOffsetInOriginal(int offset) { + if (cachedOrigDocument != null) { + try { + return cachedOrigDocument.getLineOfOffset(offset); + } catch (BadLocationException e) { + } + } + return -1; + } + public int getColumnOfOffsetInOriginal(int offset) { + if (cachedOrigDocument != null) { + try { + IRegion region = cachedOrigDocument.getLineInformationOfOffset(offset); + return offset - region.getOffset(); + } catch (BadLocationException e) { + } + } + return -1; + } + } + int originalContentMode = 0; private IFile ajFile; protected JavaCompatibleBuffer javaCompBuffer; @@ -850,17 +918,14 @@ * DO NOT PASS TO CLIENTS */ public AJCompilationUnit ajCloneCachingContents() { - return new AJCompilationUnit((PackageFragment) this.parent, this.name, this.owner) { - private char[] cachedContents; - public char[] getContents() { - if (this.cachedContents == null) - this.cachedContents = AJCompilationUnit.this.getContents(); - return this.cachedContents; - } - public CompilationUnit originalFromClone() { - return AJCompilationUnit.this; - } - }; + return new ClonedAJCU((PackageFragment) this.parent, this.name, this.owner); } + public void setConversionOptions(ConversionOptions conversionOptions) { + javaCompBuffer.setConversionOptions(conversionOptions); + } + public ConversionOptions getConversionOptions() { + return javaCompBuffer.getConversionOptions(); + } + }
diff --git a/org.eclipse.ajdt.core/src/org/eclipse/ajdt/core/parserbridge/AJCompilationUnitProblemFinder.java b/org.eclipse.ajdt.core/src/org/eclipse/ajdt/core/parserbridge/AJCompilationUnitProblemFinder.java index 76c57f4..f6d4080 100644 --- a/org.eclipse.ajdt.core/src/org/eclipse/ajdt/core/parserbridge/AJCompilationUnitProblemFinder.java +++ b/org.eclipse.ajdt.core/src/org/eclipse/ajdt/core/parserbridge/AJCompilationUnitProblemFinder.java
@@ -12,30 +12,27 @@ ******************************************************************************/ package org.eclipse.ajdt.core.parserbridge; +import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; -import java.util.Iterator; import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Set; -import org.aspectj.asm.IProgramElement; import org.eclipse.ajdt.core.AJLog; import org.eclipse.ajdt.core.codeconversion.ITDAwareCancelableNameEnvironment; import org.eclipse.ajdt.core.javaelements.AJCompilationUnit; import org.eclipse.ajdt.core.javaelements.AJCompilationUnitInfo; import org.eclipse.ajdt.core.javaelements.IntertypeElement; +import org.eclipse.ajdt.core.javaelements.AJCompilationUnit.ClonedAJCU; import org.eclipse.ajdt.core.model.AJProjectModelFacade; import org.eclipse.ajdt.core.model.AJProjectModelFactory; -import org.eclipse.ajdt.core.model.AJRelationshipManager; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.OperationCanceledException; import org.eclipse.jdt.core.ICompilationUnit; -import org.eclipse.jdt.core.IJavaElement; import org.eclipse.jdt.core.IJavaModelMarker; import org.eclipse.jdt.core.IJavaModelStatusConstants; -import org.eclipse.jdt.core.IType; import org.eclipse.jdt.core.JavaModelException; import org.eclipse.jdt.core.WorkingCopyOwner; import org.eclipse.jdt.core.compiler.CategorizedProblem; @@ -48,7 +45,9 @@ import org.eclipse.jdt.internal.compiler.env.INameEnvironment; import org.eclipse.jdt.internal.compiler.impl.CompilerOptions; import org.eclipse.jdt.internal.compiler.problem.AbortCompilation; +import org.eclipse.jdt.internal.compiler.problem.DefaultProblem; import org.eclipse.jdt.internal.compiler.problem.DefaultProblemFactory; +import org.eclipse.jdt.internal.compiler.problem.ProblemSeverities; import org.eclipse.jdt.internal.core.CancelableNameEnvironment; import org.eclipse.jdt.internal.core.CancelableProblemFactory; import org.eclipse.jdt.internal.core.CompilationUnitProblemFinder; @@ -97,10 +96,10 @@ CompilerOptions compilerOptions = new CompilerOptions(options); try { if (ajcu.getElementInfo() instanceof AJCompilationUnitInfo) { - ajcu.discardOriginalContentMode(); - this.parser = new AJSourceElementParser2( - new AJCompilationUnitStructureRequestor(ajcu, (AJCompilationUnitInfo)ajcu.getElementInfo(), null), new DefaultProblemFactory(), compilerOptions, this.options.parseLiteralExpressionsAsConstants,false); - ajcu.requestOriginalContentMode(); + this.parser = new AJSourceElementParser2( + new AJCompilationUnitStructureRequestor(ajcu, (AJCompilationUnitInfo) ajcu.getElementInfo(), null), + new DefaultProblemFactory(), + compilerOptions, this.options.parseLiteralExpressionsAsConstants,false); } else { this.parser = new CommentRecorderParser(this.problemReporter, this.options.parseLiteralExpressionsAsConstants); } @@ -151,7 +150,8 @@ ((reconcileFlags & ICompilationUnit.ENABLE_STATEMENTS_RECOVERY) != 0)), getRequestor(), problemFactory, unitElement); CompilationUnitDeclaration unit = null; - if (parser != null) { + + if (parser != null) { problemFinder.parser = parser; try { unit = parser.parseCompilationUnit( @@ -169,13 +169,13 @@ true, // analyze code true); // generate code } + CompilationResult unitResult = unit.compilationResult; CategorizedProblem[] unitProblems = unitResult.getProblems(); int length = unitProblems == null ? 0 : unitProblems.length; if (length > 0) { - CategorizedProblem[] categorizedProblems = new CategorizedProblem[length]; - System.arraycopy(unitProblems, 0, categorizedProblems, 0, - length); + CategorizedProblem[] categorizedProblems = updateProblemLocations(unitProblems, unitElement); + categorizedProblems = removeAJNonProblems(categorizedProblems, unitElement); if (categorizedProblems.length > 0) { problems.put(IJavaModelMarker.JAVA_MODEL_PROBLEM_MARKER, @@ -230,31 +230,58 @@ } /** - * removes all problems that have come from - * valid ITDs + * convert from fake positions to real positions * - * Not quite right...this will assume that all ITDs apply to all - * types declared here. So, it may erroneously remove errors. + * removes those problems that occur in fake positions + * @param problems + * @param unitElement + * @return + */ + private static CategorizedProblem[] updateProblemLocations( + CategorizedProblem[] problems, AJCompilationUnit unitElement) { + if (unitElement instanceof ClonedAJCU) { + ClonedAJCU clonedUnit = (ClonedAJCU) unitElement; + List translatedProblems = new ArrayList(problems.length); + for (int i = 0; i < problems.length; i++) { + DefaultProblem problem = (DefaultProblem) problems[i]; + int newStart = clonedUnit.translatePositionToReal(problem.getSourceStart()); + int newEnd = clonedUnit.translatePositionToReal(problem.getSourceEnd()); + if (newStart >= 0 && newEnd >= 0) { + int newLine = clonedUnit.getLineOfOffsetInOriginal(newStart); + int newColumn = clonedUnit.getColumnOfOffsetInOriginal(newStart); + translatedProblems.add(new DefaultProblem(problem.getOriginatingFileName(), + problem.getMessage(), problem.getID(), + problem.getArguments(), problem.isError() ? ProblemSeverities.Error : 0, + newStart, newEnd, + newLine >= 0 ? newLine : problem.getSourceLineNumber(), + newColumn >= 0 ? newColumn : problem.getSourceColumnNumber())); + } + } + return (CategorizedProblem[]) translatedProblems.toArray(new CategorizedProblem[translatedProblems.size()]); + } + CategorizedProblem[] categorizedProblems = new CategorizedProblem[problems.length]; + System.arraycopy(problems, 0, categorizedProblems, 0, + problems.length); + + return problems; + } + + /** + * removes all problems that have come from + * aj identifiers such as before, after, etc + * * * @param categorizedProblems * @return */ private static CategorizedProblem[] removeAJNonProblems( CategorizedProblem[] categorizedProblems, AJCompilationUnit unit) { - Set ajIdentifiers = gatherITDsForCU(unit); - boolean hasModel; - if (ajIdentifiers == null) { - // project hasn't had a successful build yet - hasModel = false; - ajIdentifiers = new HashSet(); - } else { - hasModel = true; - } - ajIdentifiers.addAll(validAJNames); + AJProjectModelFacade model = AJProjectModelFactory.getInstance().getModelForJavaElement(unit); + boolean hasModel = model.hasModel(); List newProblems = new LinkedList(); for (int i = 0; i < categorizedProblems.length; i++) { // determine if this problem should be filtered - if (isARealProblem(categorizedProblems[i], ajIdentifiers, unit, hasModel)) { + if (isARealProblem(categorizedProblems[i], unit, hasModel)) { newProblems.add(categorizedProblems[i]); } } @@ -266,7 +293,7 @@ // be eger about what we discard. If unsure // it is better to discard. because the real errors will show up when a compile happens private static boolean isARealProblem( - CategorizedProblem categorizedProblem, Set ajIdentifiers, AJCompilationUnit unit, boolean hasModel) { + CategorizedProblem categorizedProblem, AJCompilationUnit unit, boolean hasModel) { int numArgs = categorizedProblem.getArguments() == null ? 0 : categorizedProblem.getArguments().length; @@ -289,37 +316,6 @@ return false; } - if ((id == IProblem.UndefinedName || - id == IProblem.UndefinedField) && - numArgs > 0 && - ajIdentifiers.contains(firstArg)) { - // possibly from an ITD - return false; - } - - - if ((id == IProblem.UndefinedType || - id == IProblem.UndefinedMethod) && - numArgs >= 1 && - ajIdentifiers.contains(firstArg) || - ajIdentifiers.contains(secondArg)) { - // possibly from an ITD - return false; - } - - if (id == IProblem.UndefinedConstructor && - numArgs > 0) { - String[] nameParts = firstArg.split("\\."); - if (nameParts.length > 0 && - ajIdentifiers.contains(nameParts[nameParts.length-1])) { - // sometimes the error for an undefined constructor uses - // a fully qualified name in the error text. - return false; - } - } - - - if (numArgs > 1 && (id == IProblem.DuplicateField || id == IProblem.DuplicateMethod) && @@ -398,38 +394,38 @@ } - private static Set gatherITDsForCU(AJCompilationUnit unit) { - try { - AJProjectModelFacade model = AJProjectModelFactory.getInstance().getModelForJavaElement(unit); - if (model.hasModel()) { - Set/*String*/ allITDNames = new HashSet(); - IType[] types = unit.getAllTypes(); - for (int i = 0; i < types.length; i++) { - if (model.hasProgramElement(types[i])) { - List /*IRelationship*/ rels = model.getRelationshipsForElement(types[i], AJRelationshipManager.ASPECT_DECLARATIONS); - for (Iterator relIter = rels.iterator(); relIter.hasNext();) { - IJavaElement je = (IJavaElement) relIter.next(); - IProgramElement declareElt = model.javaElementToProgramElement(je); - if (declareElt != null && declareElt.getParent() != null && declareElt.getKind().isInterTypeMember()) { // checks to see if this element is valid - // should be fully qualified type and simple name - int lastDot = declareElt.getName().lastIndexOf('.'); - String name = declareElt.getName().substring(lastDot+1); - allITDNames.add(name); - } - } - } else { - // there is a problem with one of the types - // forget the whole thing and assume there is no model - return null; - } - - } - return allITDNames; - } - } catch (JavaModelException e) { - } - return null; - } +// private static Set gatherITDsForCU(AJCompilationUnit unit) { +// try { +// AJProjectModelFacade model = AJProjectModelFactory.getInstance().getModelForJavaElement(unit); +// if (model.hasModel()) { +// Set/*String*/ allITDNames = new HashSet(); +// IType[] types = unit.getAllTypes(); +// for (int i = 0; i < types.length; i++) { +// if (model.hasProgramElement(types[i])) { +// List /*IRelationship*/ rels = model.getRelationshipsForElement(types[i], AJRelationshipManager.ASPECT_DECLARATIONS); +// for (Iterator relIter = rels.iterator(); relIter.hasNext();) { +// IJavaElement je = (IJavaElement) relIter.next(); +// IProgramElement declareElt = model.javaElementToProgramElement(je); +// if (declareElt != null && declareElt.getParent() != null && declareElt.getKind().isInterTypeMember()) { // checks to see if this element is valid +// // should be fully qualified type and simple name +// int lastDot = declareElt.getName().lastIndexOf('.'); +// String name = declareElt.getName().substring(lastDot+1); +// allITDNames.add(name); +// } +// } +// } else { +// // there is a problem with one of the types +// // forget the whole thing and assume there is no model +// return null; +// } +// +// } +// return allITDNames; +// } +// } catch (JavaModelException e) { +// } +// return null; +// } static Set validAJNames = new HashSet(); static {