Bug 90388 - BCException incremental change from broken parent to List
Summary: BCException incremental change from broken parent to List
Status: RESOLVED FIXED
Alias: None
Product: AspectJ
Classification: Tools
Component: Compiler (show other bugs)
Version: 1.5.0M2   Edit
Hardware: PC Windows XP
: P3 normal (vote)
Target Milestone: 1.5.0 M3   Edit
Assignee: Adrian Colyer CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2005-04-05 17:40 EDT by Wes Isberg CLA
Modified: 2005-06-03 11:34 EDT (History)
0 users

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Wes Isberg CLA 2005-04-05 17:40:04 EDT
Find stack trace and code below.

Running AJDT in incremental mode, I had a compile error, edited to change from a
generic type to List, saved, and got the exception.

(Sorry it's not written as a test case; I'm booked now.)

from: declare parents : Result implements Iterable<Result>;
 (was compile error (incorrectly - emailed Andy))

  to: declare parents : Result implements List;

Got BCException:

------------------------------------------------------------
Internal compiler error
org.aspectj.weaver.BCException: Bad type name: 
	at org.aspectj.weaver.TypeX.nameToSignature(TypeX.java:635)
	at org.aspectj.weaver.TypeX.forName(TypeX.java:88)
	at
org.aspectj.ajdt.internal.compiler.lookup.EclipseFactory.fromBinding(EclipseFactory.java:155)
	at
org.aspectj.ajdt.internal.compiler.lookup.EclipseFactory.fromBindings(EclipseFactory.java:163)
	at
org.aspectj.ajdt.internal.compiler.lookup.EclipseFactory.makeResolvedMember(EclipseFactory.java:229)
	at
org.aspectj.ajdt.internal.compiler.lookup.EclipseFactory.makeResolvedMember(EclipseFactory.java:224)
	at
org.aspectj.ajdt.internal.compiler.problem.AjProblemReporter.abstractMethodMustBeImplemented(AjProblemReporter.java:203)
	at
org.aspectj.org.eclipse.jdt.internal.compiler.lookup.MethodVerifier.checkAbstractMethod(MethodVerifier.java:96)
	at
org.aspectj.org.eclipse.jdt.internal.compiler.lookup.MethodVerifier.checkMethods(MethodVerifier.java:305)
	at
org.aspectj.org.eclipse.jdt.internal.compiler.lookup.MethodVerifier.verify(MethodVerifier.java:575)
	at
org.aspectj.org.eclipse.jdt.internal.compiler.lookup.SourceTypeBinding.verifyMethods(SourceTypeBinding.java:1376)
	at
org.aspectj.org.eclipse.jdt.internal.compiler.lookup.SourceTypeBinding.verifyMethods(SourceTypeBinding.java:1379)
	at
org.aspectj.org.eclipse.jdt.internal.compiler.lookup.CompilationUnitScope.verifyMethods(CompilationUnitScope.java:672)
	at
org.aspectj.org.eclipse.jdt.internal.compiler.Compiler.process(Compiler.java:543)
	at
org.aspectj.org.eclipse.jdt.internal.compiler.Compiler.compile(Compiler.java:365)
	at
org.aspectj.ajdt.internal.core.builder.AjBuildManager.performCompilation(AjBuildManager.java:682)
	at
org.aspectj.ajdt.internal.core.builder.AjBuildManager.doBuild(AjBuildManager.java:168)
	at
org.aspectj.ajdt.internal.core.builder.AjBuildManager.batchBuild(AjBuildManager.java:102)
	at org.aspectj.ajde.internal.CompilerAdapter.compile(CompilerAdapter.java:122)
	at
org.aspectj.ajde.internal.AspectJBuildManager$CompilerThread.run(AspectJBuildManager.java:165)

------------------------------------------------------------------------------
/*
 */
package testing;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Stack;


public class TestContext {
    private static final ThreadLocal<TestContext> TEST_CONTEXT 
        = new ThreadLocal<TestContext>();

    /**
     * Harness calls this to start tests, get a handle to tests.
     * 
     * @return new TestContext or current one, if already started
     */
    public static TestContext startTests() {
        return getTestContext(true);
    }

    private static final void removeTestContext() {
        TEST_CONTEXT.set(null);
    }

    private static final TestContext getTestContext(boolean create) {
        TestContext result = (TestContext) TEST_CONTEXT.get();
        if ((null == result) && create) {
            result = new TestContext();
            TEST_CONTEXT.set(result);
        }
        return result;
    }

    final Stack<Result> results;
    final Result root;
    private TestContext() {
        results = new Stack<Result>();
        root = new Result(new Root());
        results.push(root);
    }

    public void startTest(ITest test) {
        assertHaveResult();
        Result parent = results.peek();
        Result child = new Result(test);
        parent.addChild(child);
        results.push(child);
        child.start();
    }

    public void endTest(ITest test) {
        doEndTest(test).pass();
        // TODO error to call directly per Invariant, but not raised?
        //doEndTest(test).setResult(null, null, null);
    }

    public void testFailure(ITest test, String message, Throwable thrown) {
        doEndTest(test).fail(message, thrown);
    }

    public void testError(ITest test, String message, Throwable thrown) {
        doEndTest(test).error(message, thrown);
    }

    private Result doEndTest(ITest test) {
        assertHaveResult();
        Result child = results.pop();
        checkSame(test, child);
        return child;
    }

    /**
     * Return the root Result, which has a pseudo-test Root.
     * The children are the tests.
     * Non-root Result returned if calls not balanced.
     * @return root Result 
     */
    public Result endTests() {
        assertHaveResult();
        Result result = results.pop();
        removeTestContext();
        return result;
    }

    protected void checkSame(ITest test, Result result) {
        if (null == test) {
            throw new IllegalArgumentException("null test");
        }
        if (null == result) {
            throw new IllegalArgumentException("null result");
        }
        if (result.test != test) {
            throw new Error("expected " + result.test + " got " + test);
        }

    }
    /** @throws IllegalStateException if no Result on stack */
    protected void assertHaveResult() {
        if (results.isEmpty()) {
            throw new IllegalStateException("empty results");
        }
    }


    static class Root implements ITest {
        private Root() {
        }

        public String toString() {
            return "Root";
        }
    }

    static aspect A {
        declare parents : Result implements List;
        //declare parents : Result implements Iterable<Result>;
    
        private final ArrayList<Result> Result.children 
            = new ArrayList<Result>();

        /** @parm child the non-null Result to add as a child */
        public void Result.addChild(Result child) {
            children.add(child);
        }

        /** @return the non-null add-able List<Result> */
        public Iterator<Result> Result.iterator() {
            return children.iterator();
        }
    }
    /**
     * A test Result with a Test, Kind, and optional message and thrown. Since
     * this is a List, results form a tree corresponding to the ITest tree.
     * A Result is world-readable, but only TestContext-writable.
     * dwNote requires DeclaringIListImplementation
     */
    public static class Result  {
        public enum Kind {
            UNSTARTED, INCOMPLETE, PASS, FAIL, ERROR
        };

        public final ITest test;


        Kind kind;

        String message;

        Throwable thrown;

        private Result(ITest test) {
            this.test = test;
            kind = Kind.UNSTARTED;
        }

        /** @return the Kind not null except during initialization */
        public Kind getKind() {
            return kind;
        }

        /** @return String message, may be null */
        public String getMessage() {
            return message;
        }

        /** @return Throwable thrown, may be null */
        public Throwable getThrown() {
            return thrown;
        }
        
        public String toString() {
            StringBuffer sb = new StringBuffer();
            TestingUtils.renderResultTree(this, sb);
            return sb.toString();
        }

        private void start() {
            setResult(Kind.INCOMPLETE, null, null);
        }

        private void pass() {
            setResult(Kind.PASS, null, null);
        }

        private void pass(String message, Throwable thrown) {
            setResult(Kind.PASS, message, thrown);
        }

        private void fail(String message, Throwable thrown) {
            setResult(Kind.FAIL, message, thrown);
        }

        private void error(String message, Throwable thrown) {
            setResult(Kind.ERROR, message, thrown);
        }

        private void setResult(Kind kind, String message, Throwable thrown) {
            this.kind = kind;
            this.message = message;
            this.thrown = thrown;
        }
    }
}
Comment 1 Andrew Clement CLA 2005-04-06 03:12:16 EDT
generics generics generics ... 1.5.0M3.
Comment 2 Andrew Clement CLA 2005-06-01 12:32:15 EDT
I believe this is fixed by the changes for bug 97763...
Comment 3 Andrew Clement CLA 2005-06-03 11:34:46 EDT
Fixed in latest dev build from http://eclipse.org/aspectj/downloads.php