aboutsummaryrefslogtreecommitdiffstats
path: root/org.aspectj.ajdt.core
diff options
context:
space:
mode:
authorwisberg <wisberg>2002-12-16 17:58:19 +0000
committerwisberg <wisberg>2002-12-16 17:58:19 +0000
commitd842c4f1139629c1f062b74ba818d233b2c31043 (patch)
tree842d3871620bc0eb60edcd95e55804d67e0f61fa /org.aspectj.ajdt.core
parent3ce247199704eae6b2c92c6e38c69584e3250c52 (diff)
downloadaspectj-d842c4f1139629c1f062b74ba818d233b2c31043.tar.gz
aspectj-d842c4f1139629c1f062b74ba818d233b2c31043.zip
initial version
Diffstat (limited to 'org.aspectj.ajdt.core')
-rw-r--r--org.aspectj.ajdt.core/.classpath18
-rw-r--r--org.aspectj.ajdt.core/.project24
-rw-r--r--org.aspectj.ajdt.core/scripts/makedelegate.py28
-rw-r--r--org.aspectj.ajdt.core/scripts/makeparser.py126
-rw-r--r--org.aspectj.ajdt.core/src/.cvsignore1
-rw-r--r--org.aspectj.ajdt.core/src/org/aspectj/ajdt/ajc/AjdtCommand.java125
-rw-r--r--org.aspectj.ajdt.core/src/org/aspectj/ajdt/ajc/BuildArgParser.java415
-rw-r--r--org.aspectj.ajdt.core/src/org/aspectj/ajdt/ajc/messages.properties117
-rw-r--r--org.aspectj.ajdt.core/src/org/aspectj/ajdt/compiler/IAjTerminalSymbols.java24
-rw-r--r--org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/AjCompiler.java65
-rw-r--r--org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/AdviceDeclaration.java350
-rw-r--r--org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/AspectClinit.java48
-rw-r--r--org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/AspectDeclaration.java705
-rw-r--r--org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/AstUtil.java256
-rw-r--r--org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/DeclareDeclaration.java114
-rw-r--r--org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/EclipseAttributeAdapter.java34
-rw-r--r--org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/IAjDeclaration.java22
-rw-r--r--org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/IfMethodDeclaration.java55
-rw-r--r--org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/IfPseudoToken.java111
-rw-r--r--org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/InterTypeConstructorDeclaration.java256
-rw-r--r--org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/InterTypeDeclaration.java131
-rw-r--r--org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/InterTypeFieldDeclaration.java286
-rw-r--r--org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/InterTypeMethodDeclaration.java175
-rw-r--r--org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/KnownFieldReference.java39
-rw-r--r--org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/KnownMessageSend.java57
-rw-r--r--org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/PointcutDeclaration.java171
-rw-r--r--org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/PointcutDesignator.java88
-rw-r--r--org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/Proceed.java123
-rw-r--r--org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/PseudoToken.java85
-rw-r--r--org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/PseudoTokens.java147
-rw-r--r--org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/SuperFixerVisitor.java68
-rw-r--r--org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/ThisJoinPointVisitor.java224
-rw-r--r--org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/AjLookupEnvironment.java201
-rw-r--r--org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/AjTypeConstants.java68
-rw-r--r--org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/EclipseAdvice.java46
-rw-r--r--org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/EclipseObjectType.java123
-rw-r--r--org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/EclipseScope.java254
-rw-r--r--org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/EclipseShadow.java132
-rw-r--r--org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/EclipseSourceLocation.java65
-rw-r--r--org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/EclipseTypeMunger.java141
-rw-r--r--org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/EclipseWorld.java263
-rw-r--r--org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/HelperInterfaceBinding.java99
-rw-r--r--org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/InterTypeFieldBinding.java113
-rw-r--r--org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/InterTypeMemberFinder.java401
-rw-r--r--org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/InterTypeMethodBinding.java147
-rw-r--r--org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/InterTypeScope.java51
-rw-r--r--org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/PointcutBinding.java36
-rw-r--r--org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/PrivilegedFieldBinding.java68
-rw-r--r--org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/PrivilegedHandler.java63
-rw-r--r--org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/SimpleSyntheticAccessMethodBinding.java27
-rw-r--r--org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/parser/AjParser.java2251
-rw-r--r--org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/parser/AjScanner.java74
-rw-r--r--org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/parser/parser1.rscbin0 -> 46914 bytes
-rw-r--r--org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/parser/parser2.rscbin0 -> 46084 bytes
-rw-r--r--org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/parser/parser3.rscbin0 -> 1364 bytes
-rw-r--r--org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/parser/parser4.rscbin0 -> 2690 bytes
-rw-r--r--org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/parser/parser5.rscbin0 -> 710 bytes
-rw-r--r--org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/problem/AjProblemReporter.java135
-rw-r--r--org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/AjBuildConfig.java205
-rw-r--r--org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/AjBuildManager.java845
-rw-r--r--org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/AjCompilerOptions.java28
-rw-r--r--org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/AjNameEnvironment.java40
-rw-r--r--org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/AsmBuilder.java317
-rw-r--r--org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/ClassFileCache.java184
-rw-r--r--org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/ClassFileCacheFolder.java140
-rw-r--r--org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/ClasspathContainer.java81
-rw-r--r--org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/ClasspathSourcefiles.java42
-rw-r--r--org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/CommandLineResourceDelta.java82
-rw-r--r--org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/DeferredWriteFile.java179
-rw-r--r--org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/EclipseAdapterUtils.java141
-rw-r--r--org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/EclipseMessageHandler.java190
-rw-r--r--org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/EclipseSourceContext.java37
-rw-r--r--org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/EclipseUnwovenClassFile.java113
-rw-r--r--org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/EmacsStructureModelManager.java217
-rw-r--r--org.aspectj.ajdt.core/src/org/aspectj/tools/ajc/Main.java562
-rw-r--r--org.aspectj.ajdt.core/src/org/aspectj/workbench/resources/AbstractContainer.java64
-rw-r--r--org.aspectj.ajdt.core/src/org/aspectj/workbench/resources/AbstractFile.java121
-rw-r--r--org.aspectj.ajdt.core/src/org/aspectj/workbench/resources/AbstractFolder.java62
-rw-r--r--org.aspectj.ajdt.core/src/org/aspectj/workbench/resources/AbstractResource.java248
-rw-r--r--org.aspectj.ajdt.core/src/org/aspectj/workbench/resources/FilesystemFile.java193
-rw-r--r--org.aspectj.ajdt.core/src/org/aspectj/workbench/resources/FilesystemFolder.java134
-rw-r--r--org.aspectj.ajdt.core/src/org/aspectj/workbench/resources/SimpleProject.java136
-rw-r--r--org.aspectj.ajdt.core/testdata/Hello.txt13
-rw-r--r--org.aspectj.ajdt.core/testdata/ajc/A.java0
-rw-r--r--org.aspectj.ajdt.core/testdata/ajc/B.java0
-rw-r--r--org.aspectj.ajdt.core/testdata/ajc/X.aj0
-rw-r--r--org.aspectj.ajdt.core/testdata/ajc/Y.aj0
-rw-r--r--org.aspectj.ajdt.core/testdata/ajc/pkg/Hello.java3
-rw-r--r--org.aspectj.ajdt.core/testdata/lintspec.properties0
-rw-r--r--org.aspectj.ajdt.core/testdata/resources/empty.txt0
-rw-r--r--org.aspectj.ajdt.core/testdata/resources/file.txt2
-rw-r--r--org.aspectj.ajdt.core/testdata/resources/javaFile.txt2
-rw-r--r--org.aspectj.ajdt.core/testdata/src1/.cvsignore2
-rw-r--r--org.aspectj.ajdt.core/testdata/src1/A.java41
-rw-r--r--org.aspectj.ajdt.core/testdata/src1/A1.java23
-rw-r--r--org.aspectj.ajdt.core/testdata/src1/A2.java19
-rw-r--r--org.aspectj.ajdt.core/testdata/src1/Ap.java51
-rw-r--r--org.aspectj.ajdt.core/testdata/src1/AroundA.java27
-rw-r--r--org.aspectj.ajdt.core/testdata/src1/AroundA1.java45
-rw-r--r--org.aspectj.ajdt.core/testdata/src1/BadA.java35
-rw-r--r--org.aspectj.ajdt.core/testdata/src1/BadBinding.java22
-rw-r--r--org.aspectj.ajdt.core/testdata/src1/BadHello.java6
-rw-r--r--org.aspectj.ajdt.core/testdata/src1/DeclareSoft.java26
-rw-r--r--org.aspectj.ajdt.core/testdata/src1/DeclareWarning.java11
-rw-r--r--org.aspectj.ajdt.core/testdata/src1/Declares.java13
-rw-r--r--org.aspectj.ajdt.core/testdata/src1/DummyAspect.java6
-rw-r--r--org.aspectj.ajdt.core/testdata/src1/Good.java61
-rw-r--r--org.aspectj.ajdt.core/testdata/src1/Handler.java50
-rw-r--r--org.aspectj.ajdt.core/testdata/src1/Hello.java5
-rw-r--r--org.aspectj.ajdt.core/testdata/src1/IfPcd.java37
-rw-r--r--org.aspectj.ajdt.core/testdata/src1/Initialization.java46
-rw-r--r--org.aspectj.ajdt.core/testdata/src1/InterType.java86
-rw-r--r--org.aspectj.ajdt.core/testdata/src1/InterTypeConstructors.java73
-rw-r--r--org.aspectj.ajdt.core/testdata/src1/InterTypeMethods.java79
-rw-r--r--org.aspectj.ajdt.core/testdata/src1/MyTrace.java7
-rw-r--r--org.aspectj.ajdt.core/testdata/src1/Parents.java40
-rw-r--r--org.aspectj.ajdt.core/testdata/src1/ParentsFail.java22
-rw-r--r--org.aspectj.ajdt.core/testdata/src1/PerCflow.java22
-rw-r--r--org.aspectj.ajdt.core/testdata/src1/PerObject.java22
-rw-r--r--org.aspectj.ajdt.core/testdata/src1/Privileged.java32
-rw-r--r--org.aspectj.ajdt.core/testdata/src1/ThisAndModifiers.java19
-rw-r--r--org.aspectj.ajdt.core/testdata/src1/Trace.java22
-rw-r--r--org.aspectj.ajdt.core/testdata/src1/TraceHello.java5
-rw-r--r--org.aspectj.ajdt.core/testdata/src1/UnimplementedSyntax.java23
-rw-r--r--org.aspectj.ajdt.core/testdata/src1/Xlint.java3
-rw-r--r--org.aspectj.ajdt.core/testdata/src1/p1/.cvsignore1
-rw-r--r--org.aspectj.ajdt.core/testdata/src1/p1/A.java28
-rw-r--r--org.aspectj.ajdt.core/testdata/src1/p1/Foo.java7
-rw-r--r--org.aspectj.ajdt.core/testdata/src1/trace/ExecTrace.java7
-rw-r--r--org.aspectj.ajdt.core/testdata/src1/trace/MegaTrace.java33
-rw-r--r--org.aspectj.ajdt.core/testdata/src1/tracep1/TraceTest.java11
-rw-r--r--org.aspectj.ajdt.core/testdata/testclasses.jarbin0 -> 1141 bytes
-rw-r--r--org.aspectj.ajdt.core/testdata/testclasses/Hello.java5
-rw-r--r--org.aspectj.ajdt.core/testdata/testclasses/p1/Foo.classbin0 -> 510 bytes
-rw-r--r--org.aspectj.ajdt.core/testdata/testclasses/p1/Foo.java7
-rw-r--r--org.aspectj.ajdt.core/testsrc/AroundAMain.java47
-rw-r--r--org.aspectj.ajdt.core/testsrc/EajcModuleTests.java33
-rw-r--r--org.aspectj.ajdt.core/testsrc/org/aspectj/ajdt/ajc/AjdtAjcTests.java33
-rw-r--r--org.aspectj.ajdt.core/testsrc/org/aspectj/ajdt/ajc/AjdtCommandTestCase.java111
-rw-r--r--org.aspectj.ajdt.core/testsrc/org/aspectj/ajdt/ajc/BuildArgParserTestCase.java401
-rw-r--r--org.aspectj.ajdt.core/testsrc/org/aspectj/ajdt/ajc/ConsoleMessageHandlerTestCase.java62
-rw-r--r--org.aspectj.ajdt.core/testsrc/org/aspectj/ajdt/internal/compiler/batch/AjdtBatchTests.java39
-rw-r--r--org.aspectj.ajdt.core/testsrc/org/aspectj/ajdt/internal/compiler/batch/BasicCommandTestCase.java103
-rw-r--r--org.aspectj.ajdt.core/testsrc/org/aspectj/ajdt/internal/compiler/batch/BcweaverJarMaker.java90
-rw-r--r--org.aspectj.ajdt.core/testsrc/org/aspectj/ajdt/internal/compiler/batch/BinaryFormsTestCase.java52
-rw-r--r--org.aspectj.ajdt.core/testsrc/org/aspectj/ajdt/internal/compiler/batch/CommandTestCase.java160
-rw-r--r--org.aspectj.ajdt.core/testsrc/org/aspectj/ajdt/internal/compiler/batch/CompileAndRunTestCase.java90
-rw-r--r--org.aspectj.ajdt.core/testsrc/org/aspectj/ajdt/internal/compiler/batch/ImageTestCase.java58
-rw-r--r--org.aspectj.ajdt.core/testsrc/org/aspectj/ajdt/internal/compiler/batch/IncrementalCase.java485
-rw-r--r--org.aspectj.ajdt.core/testsrc/org/aspectj/ajdt/internal/compiler/batch/MultipleCompileTestCase.java35
-rw-r--r--org.aspectj.ajdt.core/testsrc/org/aspectj/ajdt/internal/compiler/batch/VerifyWeaveTestCase.java114
-rw-r--r--org.aspectj.ajdt.core/testsrc/org/aspectj/ajdt/internal/compiler/batch/WorkingTestMain.java131
-rw-r--r--org.aspectj.ajdt.core/testsrc/org/aspectj/ajdt/internal/core/builder/AjBuildManagerTest.java366
-rw-r--r--org.aspectj.ajdt.core/testsrc/org/aspectj/ajdt/internal/core/builder/AjdtBuilderTests.java33
-rw-r--r--org.aspectj.ajdt.core/testsrc/org/aspectj/ajdt/internal/core/builder/ClassFileCacheTest.java253
-rw-r--r--org.aspectj.ajdt.core/testsrc/org/aspectj/ajdt/internal/core/builder/ClasspathContainerTestCase.java66
-rw-r--r--org.aspectj.ajdt.core/testsrc/org/aspectj/workbench/resources/FilesystemFileTest.java112
-rw-r--r--org.aspectj.ajdt.core/testsrc/org/aspectj/workbench/resources/FilesystemFolderTest.java128
-rw-r--r--org.aspectj.ajdt.core/testsrc/org/aspectj/workbench/resources/WorkspaceResourcesTests.java31
159 files changed, 17740 insertions, 0 deletions
diff --git a/org.aspectj.ajdt.core/.classpath b/org.aspectj.ajdt.core/.classpath
new file mode 100644
index 000000000..f1022a482
--- /dev/null
+++ b/org.aspectj.ajdt.core/.classpath
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="src" path="src"/>
+ <classpathentry kind="var" path="JRE_LIB" rootpath="JRE_SRCROOT" sourcepath="JRE_SRC"/>
+ <classpathentry kind="src" path="/org.eclipse.jdt.core"/>
+ <classpathentry kind="src" path="/bridge"/>
+ <classpathentry kind="src" path="/weaver"/>
+ <classpathentry kind="src" path="/asm"/>
+ <classpathentry kind="src" path="/util"/>
+ <classpathentry kind="src" path="/runtime"/>
+ <classpathentry kind="src" path="testsrc"/>
+ <classpathentry kind="lib" path="/lib/bcel/bcel.jar"
+ rootpath="bcel-5.0/src/java" sourcepath="/lib/bcel/bcel-src.zip"/>
+ <classpathentry kind="lib" path="/lib/junit/junit.jar" sourcepath="/lib/junit/junit-src.jar"/>
+ <classpathentry kind="lib" path="/lib/eclipse2.0/jdtDepends.jar" sourcepath="/lib/eclipse2.0/jdtDependsSrc.zip"/>
+ <classpathentry kind="src" path="/testing-util"/>
+ <classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/org.aspectj.ajdt.core/.project b/org.aspectj.ajdt.core/.project
new file mode 100644
index 000000000..301a33091
--- /dev/null
+++ b/org.aspectj.ajdt.core/.project
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>org.aspectj.ajdt.core</name>
+ <comment></comment>
+ <projects>
+ <project>asm</project>
+ <project>weaver</project>
+ <project>bridge</project>
+ <project>org.eclipse.jdt.core</project>
+ <project>runtime</project>
+ <project>testing-util</project>
+ <project>util</project>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ </natures>
+</projectDescription>
diff --git a/org.aspectj.ajdt.core/scripts/makedelegate.py b/org.aspectj.ajdt.core/scripts/makedelegate.py
new file mode 100644
index 000000000..682a338f0
--- /dev/null
+++ b/org.aspectj.ajdt.core/scripts/makedelegate.py
@@ -0,0 +1,28 @@
+inputFile = "c:/eclipse/workspace/org.eclipse.jdt.core/aspectj/org/aspectj/workbench/resources/FileAdapter.java"
+
+text = open(inputFile, 'r').read()
+
+#print text
+
+import re, string
+
+methodPat = re.compile(r"public [^{]*\([^{]*{[^}]*}") #^[{]\)^[{]{", re.DOTALL) #{ .* }", re.DOTALL)
+
+throwException = """throw new RuntimeException("unimplemented");"""
+
+for method in methodPat.findall(text):
+ print method
+
+ newMethod = method[:len(method)-1]
+
+ startBody = newMethod.find("{")
+ newMethod = newMethod[:startBody+1]
+
+
+ newMethod = newMethod + "\n\t" + throwException + "\n\t}"
+ text = text.replace(method, newMethod)
+
+print text
+
+open(inputFile, 'w').write(text)
+
diff --git a/org.aspectj.ajdt.core/scripts/makeparser.py b/org.aspectj.ajdt.core/scripts/makeparser.py
new file mode 100644
index 000000000..1b2af4191
--- /dev/null
+++ b/org.aspectj.ajdt.core/scripts/makeparser.py
@@ -0,0 +1,126 @@
+# set these first four variables appropriately for your system
+eclipseWorkspace = "c:/eclipse/workspace"
+workingDir = "c:/apps/jikespg/jdt/tmp"
+
+jikespg = "c:/apps/jikespg/src/a.exe"
+makersc = "c:/jdk1.4/bin/java -classpath c:/eclipse/workspace/org.eclipse.jdt.core/bin;c:/apps/jikespg/jdt;c:/eclipse/workspace/bcweaver/bin UpdateParserFiles"
+
+# the rest of this should never change
+ajCompilerHomeRel = "org.aspectj.ajdt.core/src/"
+javaCompilerHomeRel = "org.eclipse.jdt.core/compiler/"
+
+compilerHomeRel = ajCompilerHomeRel
+parserHomeRel = ajCompilerHomeRel + "org/aspectj/ajdt/internal/compiler/parser"
+parserInfoFileRel = javaCompilerHomeRel + "org/eclipse/jdt/internal/compiler/parser/ParserBasicInformation.java"
+symbolsHomeRel = javaCompilerHomeRel + "org/eclipse/jdt/core/compiler/ITerminalSymbols.java"
+# symbolsHomeRel = "org/aspectj/ajdt/compiler/IAjTerminalSymbols.java"
+parserClass = "AjParser.java"
+grammarFileRel = javaCompilerHomeRel + "org/eclipse/jdt/internal/compiler/parser/aj_grammar.txt"
+
+
+import os
+from os import path
+import re
+
+def readFile(name, mode=''):
+ f = open(name, 'r'+mode)
+ text = f.read()
+ f.close()
+ return text
+
+def writeFile(name, text, mode=''):
+ f = open(name, 'w'+mode)
+ f.write(text)
+ f.close()
+
+compilerHome = path.join(eclipseWorkspace, compilerHomeRel)
+parserHome = path.join(eclipseWorkspace, parserHomeRel)
+symbolFile = path.join(eclipseWorkspace, symbolsHomeRel)
+parserInfoFile = path.join(eclipseWorkspace, parserInfoFileRel)
+
+parserFile = path.join(parserHome, parserClass)
+parserText = readFile(parserFile)
+
+if grammarFileRel == None:
+ r = re.compile(r"public final static void grammar\(\){.*(--main.*\$end\n)-- need", re.DOTALL)
+ match = r.search(parserText)
+ grammar = match.group(1)
+else:
+ grammar = readFile(path.join(eclipseWorkspace, grammarFileRel))
+#print grammar
+
+grammarFile = path.join(workingDir, "java.g")
+writeFile(grammarFile, grammar)
+os.chdir(workingDir)
+os.system("%s java.g" % jikespg)
+
+#3.1 Copy the contents of the JavaAction.java file into the consumeRule(int) method of the org.eclipse.jdt.internal.compiler.parser.Parser class.
+
+newConsumeRule = readFile(path.join(workingDir, "JavaAction.java"))
+#print newConsumeRule
+
+r = re.compile(r"(// This method is part of an automatic generation : do NOT edit-modify\W+protected void consumeRule\(int act\) {.*)protected void consumeSimpleAssertStatement\(\) {", re.DOTALL)
+
+match = r.search(parserText)
+parserText = parserText.replace(match.group(1), newConsumeRule)
+
+
+#3.2 The definition of the Parser needs to be updated with two tables from javadcl.java. Those are rhs[] and name[].
+
+newTables = readFile(path.join(workingDir, "javadcl.java"))
+r = re.compile(r"(public final static byte rhs\[\] = \{[^}]*\};)", re.DOTALL)
+rhsTable = r.search(newTables).group(0)
+
+parserText = parserText.replace(r.search(parserText).group(0), rhsTable)
+
+
+r = re.compile(r"(public final static String name\[\] = \{[^}]*\}[^}]*\};)", re.DOTALL)
+nameTable = r.search(newTables).group(0)
+nameTable = nameTable.replace("\"$eof\"", "UNEXPECTED_EOF")
+nameTable = nameTable.replace("$error", "Invalid Character")
+
+parserText = parserText.replace(r.search(parserText).group(0), nameTable)
+
+
+#we're done w/ Parser.java
+writeFile(parserFile, parserText)
+
+
+
+#3.3 The class org.eclipse.jdt.internal.compiler.parser.ParserBasicInformation needs to be updated with the content of the file javadef.java.
+
+defs = readFile(path.join(workingDir, "javadef.java"))
+r = re.compile(r"(public final static int[^;]*;)", re.DOTALL)
+syms = r.search(defs).group(0)
+#print syms
+
+text = readFile(parserInfoFile)
+text = text.replace(r.search(text).group(0), syms)
+
+writeFile(parserInfoFile, text)
+
+#3.4 This is the contents of the class org.eclipse.jdt.internal.compiler.parser.TerminalSymbols.
+
+defs = readFile(path.join(workingDir, "javasym.java"))
+r = re.compile(r"(public final static int[^;]*;)", re.DOTALL)
+syms = r.search(defs).group(0)
+syms = syms.replace("$eof", "EOF")
+syms = syms.replace("$error", "ERROR")
+
+print syms
+
+text = readFile(symbolFile)
+text = text.replace(r.search(text).group(0), syms)
+
+writeFile(symbolFile, text)
+
+#3.5 The last step is to update the resource files:
+
+os.chdir(workingDir)
+os.system("%s javadcl.java" % makersc)
+
+for i in range(1,6):
+ name = "parser%d.rsc" % i
+ print "moving", name
+ t = readFile(path.join(workingDir, name), 'b')
+ writeFile(path.join(parserHome, name), t, 'b')
diff --git a/org.aspectj.ajdt.core/src/.cvsignore b/org.aspectj.ajdt.core/src/.cvsignore
new file mode 100644
index 000000000..a3f0b1b77
--- /dev/null
+++ b/org.aspectj.ajdt.core/src/.cvsignore
@@ -0,0 +1 @@
+*.lst
diff --git a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/ajc/AjdtCommand.java b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/ajc/AjdtCommand.java
new file mode 100644
index 000000000..1cecb4a76
--- /dev/null
+++ b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/ajc/AjdtCommand.java
@@ -0,0 +1,125 @@
+/* *******************************************************************
+ * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC).
+ * All rights reserved.
+ * This program and the accompanying materials are made available
+ * under the terms of the Common Public License v1.0
+ * which accompanies this distribution and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * Xerox/PARC initial implementation
+ * ******************************************************************/
+
+
+package org.aspectj.ajdt.ajc;
+
+import org.aspectj.ajdt.internal.core.builder.AjBuildConfig;
+import org.aspectj.ajdt.internal.core.builder.AjBuildManager;
+import org.aspectj.bridge.*;
+import org.aspectj.util.LangUtil;
+import org.eclipse.jdt.internal.core.builder.MissingSourceFileException;
+
+import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.List;
+
+/**
+ * ICommand adapter for the AspectJ eclipse-based compiler.
+ */
+public class AjdtCommand implements ICommand {
+
+ /** Message String for any AbortException thrown from ICommand API's */
+ public static final String ABORT_MESSAGE = "ABORT";
+
+ private boolean canRepeatCommand = true;
+
+ AjBuildManager buildManager = null;
+ String[] savedArgs = null;
+
+ /**
+ * Run AspectJ compiler, wrapping any exceptions thrown as
+ * ABORT messages (containing ABORT_MESSAGE String).
+ * @param args the String[] for the compiler
+ * @param handler the IMessageHandler for any messages
+ * @see org.aspectj.bridge.ICommand#runCommand(String[], IMessageHandler)
+ * @return false if command failed
+ */
+ public boolean runCommand(String[] args, IMessageHandler handler) {
+ try {
+ buildManager = new AjBuildManager(handler);
+ savedArgs = new String[args.length];
+ System.arraycopy(args, 0, savedArgs, 0, savedArgs.length);
+ CountingMessageHandler counter = new CountingMessageHandler(handler);
+ AjBuildConfig config = genBuildConfig(savedArgs, counter);
+ return (!counter.hasErrors()
+ && buildManager.batchBuild(config, counter)
+ && !counter.hasErrors());
+ } catch (AbortException ae) {
+ if (AbortException.ABORT.equals(ae)) {
+ throw ae;
+ } else {
+ MessageUtil.abort(handler, ABORT_MESSAGE, ae);
+ return false;
+ }
+ } catch (MissingSourceFileException t) { // XXX special handling - here only?
+ MessageUtil.error(handler, t.getMessage());
+ return false;
+ } catch (Throwable t) {
+ //System.err.println("caught: " + t);
+ MessageUtil.abort(handler, ABORT_MESSAGE, t);
+ return false;
+ }
+ }
+
+ /**
+ * Run AspectJ compiler, wrapping any exceptions thrown as
+ * ABORT messages (containing ABORT_MESSAGE String).
+ * @see org.aspectj.bridge.ICommand#repeatCommand(IMessageHandler)
+ * @return false if command failed
+ */
+ public boolean repeatCommand(IMessageHandler handler) {
+ if (null == buildManager) {
+ MessageUtil.abort(handler, "repeatCommand called before runCommand");
+ return false;
+ }
+ try {
+ //buildManager.setMessageHandler(handler);
+ CountingMessageHandler counter = new CountingMessageHandler(handler);
+ // regenerate configuration b/c world might have changed (?)
+ AjBuildConfig config = genBuildConfig(savedArgs, counter);
+ return (!counter.hasErrors()
+ && buildManager.incrementalBuild(config, handler)
+ && !counter.hasErrors());
+ } catch (MissingSourceFileException t) {
+ return false; // already converted to error
+ } catch (Throwable t) {
+ MessageUtil.abort(handler, ABORT_MESSAGE, t);
+ return false;
+ }
+ }
+
+ /** @throws AbortException.ABORT on error after logging message */
+ AjBuildConfig genBuildConfig(String[] args, IMessageHandler handler) {
+ BuildArgParser parser = new BuildArgParser();
+ AjBuildConfig config = parser.genBuildConfig(args, handler);
+ String message = parser.getOtherMessages(true);
+
+ if (null != message) {
+ IMessage.Kind kind = inferKind(message);
+ handler.handleMessage(new Message(message, kind, null, null));
+ throw AbortException.ABORT; // XXX tangled - assumes handler prints?
+ }
+ return config;
+ }
+
+ /** @return IMessage.WARNING unless message contains error or info */
+ protected IMessage.Kind inferKind(String message) { // XXX dubious
+ if (-1 == message.indexOf("error")) {
+ return IMessage.ERROR;
+ } else if (-1 == message.indexOf("info")) {
+ return IMessage.INFO;
+ } else {
+ return IMessage.WARNING;
+ }
+ }
+}
diff --git a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/ajc/BuildArgParser.java b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/ajc/BuildArgParser.java
new file mode 100644
index 000000000..81cabdb69
--- /dev/null
+++ b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/ajc/BuildArgParser.java
@@ -0,0 +1,415 @@
+/* *******************************************************************
+ * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC).
+ * All rights reserved.
+ * This program and the accompanying materials are made available
+ * under the terms of the Common Public License v1.0
+ * which accompanies this distribution and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * Xerox/PARC initial implementation
+ * ******************************************************************/
+
+
+
+package org.aspectj.ajdt.ajc;
+
+import java.io.*;
+import java.util.*;
+import org.aspectj.ajdt.internal.core.builder.*;
+import org.aspectj.weaver.bcel.*;
+import org.apache.bcel.util.ClassPath;
+import org.aspectj.bridge.*;
+import org.aspectj.bridge.IMessage.Kind;
+import org.aspectj.util.*;
+import org.eclipse.jdt.core.JavaCore;
+import org.eclipse.jdt.core.compiler.*;
+import org.eclipse.jdt.internal.compiler.*;
+import org.eclipse.jdt.internal.compiler.batch.*;
+import org.eclipse.jdt.internal.compiler.problem.*;
+import org.eclipse.jdt.internal.core.util.*;
+import org.aspectj.ajdt.internal.core.builder.AjCompilerOptions;
+import org.aspectj.util.ConfigParser;
+import org.eclipse.jdt.core.compiler.InvalidInputException;
+import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
+
+public class BuildArgParser extends org.eclipse.jdt.internal.compiler.batch.Main {
+
+ private static final String BUNDLE_NAME = "org.aspectj.ajdt.ajc.messages";
+
+ /** to initialize super's PrintWriter but refer to underlying StringWriter */
+ private static class StringPrintWriter extends PrintWriter {
+ public final StringWriter stringWriter;
+ StringPrintWriter(StringWriter sw) {
+ super(sw);
+ this.stringWriter = sw;
+ }
+ }
+
+ /**
+ * StringWriter sink for some errors.
+ * This only captures errors not handled by any IMessageHandler parameter
+ * and only when no PrintWriter is set in the constructor.
+ * XXX This relies on (Sun's) implementation of StringWriter,
+ * which returns the actual (not copy) internal StringBuffer.
+ */
+ private final StringBuffer errorSink;
+
+ /**
+ * Overrides super's bundle.
+ */
+ public BuildArgParser(PrintWriter writer) {
+ super(writer, false);
+ bundle = ResourceBundle.getBundle(BUNDLE_NAME);
+ if (writer instanceof StringPrintWriter) {
+ errorSink = ((StringPrintWriter) writer).stringWriter.getBuffer();
+ } else {
+ errorSink = null;
+ }
+ }
+
+ /** Set up to capture messages using getOtherMessages(boolean) */
+ public BuildArgParser() {
+ this(new StringPrintWriter(new StringWriter()));
+ }
+
+ public AjBuildConfig genBuildConfig(String[] args, IMessageHandler handler) {
+ AjBuildConfig buildConfig = new AjBuildConfig();
+ try {
+ // sets filenames to be non-null in order to make sure that file paramters are ignored
+ super.filenames = new String[] { "" };
+
+ List optionsList = new ArrayList(Arrays.asList(args));
+ List fileList = new ArrayList();
+ boolean incrementalMode = false;
+ if (optionsList.remove("-incremental")) {
+ incrementalMode = true;
+ args = (String[])optionsList.toArray(new String[optionsList.size()]);
+ }
+
+ AjcConfigParser parser = new AjcConfigParser(buildConfig, handler, incrementalMode);
+ parser.parseCommandLine(args);
+
+ if (!incrementalMode) {
+ if (parser.getFiles() != null) {
+ for (Iterator it = parser.getFiles().iterator(); it.hasNext(); ) {
+ fileList.add((File)it.next());
+ }
+ }
+ } else {
+ if (parser.getFiles() != null && !parser.getFiles().isEmpty()) {
+ handler.handleMessage(new Message("can not directly specify files in incremental mode, use -sourceroots instead",
+ Message.ERROR, null, null));
+ }
+ }
+
+ List javaArgList = parser.getUnparsedArgs();
+ if (javaArgList.size() != 0) {
+ super.configure((String[])javaArgList.toArray(new String[javaArgList.size()]));
+ }
+
+ if (buildConfig.getSourceRoots() != null) {
+ for (Iterator i = buildConfig.getSourceRoots().iterator(); i.hasNext(); ) {
+ fileList.addAll(collectSourceRootFiles((File)i.next()));
+ }
+ }
+
+ buildConfig.setFiles(fileList);
+ if (destinationPath != null) {
+ buildConfig.setOutputDir(new File(destinationPath));
+ }
+
+ buildConfig.setClasspath(getClasspath(parser));
+
+ if (incrementalMode) {
+ if (buildConfig.getSourceRoots().size() == 0) {
+ handler.handleMessage(new Message("must specify a source root when in incremental mode",
+ Message.ERROR, null, null));
+ }
+ }
+
+ setDebugOptions();
+ buildConfig.setJavaOptions(options);
+ } catch (InvalidInputException iie) {
+ handler.handleMessage(new Message(iie.getMessage(), Message.ERROR, null, null));
+ printUsage();
+ }
+ return buildConfig;
+ }
+
+ /**
+ * Get messages not dumped to handler or any PrintWriter.
+ * @param flush if true, empty errors
+ * @return null if none, String otherwise
+ * @see BuildArgParser()
+ */
+ public String getOtherMessages(boolean flush) {
+ if (null == errorSink) {
+ return null;
+ }
+
+ String result = errorSink.toString().trim();
+ if (0 == result.length()) {
+ result = null;
+ }
+ if (flush) {
+ errorSink.setLength(0);
+ }
+ return result;
+ }
+
+ private void setDebugOptions() {
+ options.put(
+ CompilerOptions.OPTION_LocalVariableAttribute,
+ CompilerOptions.GENERATE);
+ options.put(
+ CompilerOptions.OPTION_LineNumberAttribute,
+ CompilerOptions.GENERATE);
+ options.put(
+ CompilerOptions.OPTION_SourceFileAttribute,
+ CompilerOptions.GENERATE);
+ }
+
+
+ private Collection collectSourceRootFiles(File dir) {
+ return Arrays.asList(FileUtil.listFiles(dir, FileUtil.aspectjSourceFileFilter));
+ }
+
+
+ public List getClasspath(AjcConfigParser parser) {
+ List ret = new ArrayList();
+
+ if (parser.bootclasspath == null) {
+ addClasspath(System.getProperty("sun.boot.class.path", ""), ret);
+ } else {
+ addClasspath(parser.bootclasspath, ret);
+ }
+
+ String extdirs = parser.extdirs;
+ if (extdirs == null) {
+ extdirs = System.getProperty("java.ext.dirs", "");
+ }
+ addExtDirs(extdirs, ret);
+
+ if ((classpaths == null || classpaths.length == 0) ||
+ (classpaths != null && classpaths[0] == ".")) {
+ //??? this puts the compiler's classes on the classpath
+ //??? this is ajc-1.0 compatible
+ addClasspath(System.getProperty("java.class.path", ""), ret);
+ } else {
+ ret.addAll(Arrays.asList(classpaths));
+ }
+
+ //??? eclipse seems to put outdir on the classpath
+ //??? we're brave and believe we don't need it
+
+ return ret;
+ }
+
+ private void addExtDirs(String extdirs, List classpathCollector) {
+ StringTokenizer tokenizer = new StringTokenizer(extdirs, File.pathSeparator);
+ while (tokenizer.hasMoreTokens()) {
+// classpathCollector.add(tokenizer.nextToken());
+ File dirFile = new File((String)tokenizer.nextToken());
+ if (dirFile.exists() && dirFile.isDirectory()) {
+ File[] files = FileUtil.listFiles(dirFile, new FileFilter() {
+ public boolean accept(File pathname) {
+ return pathname.isFile() && pathname.getName().endsWith(".jar");
+ }
+ });
+ for (int i = 0; i < files.length; i++) {
+ classpathCollector.add(files[i].getAbsolutePath());
+ }
+ }
+ }
+ }
+
+
+ private void addClasspath(String classpath, List classpathCollector) {
+ StringTokenizer tokenizer = new StringTokenizer(classpath, File.pathSeparator);
+ while (tokenizer.hasMoreTokens()) {
+ classpathCollector.add(tokenizer.nextToken());
+ }
+ }
+
+ // !!! extract error handling to be common so that the IDEs can use it
+ private class AjcConfigParser extends ConfigParser {
+ private String bootclasspath = null;
+ private String extdirs = null;
+ private boolean incrementalArgsMode = false;
+ private List unparsedArgs = new ArrayList();
+ private AjBuildConfig buildConfig;
+ private IMessageHandler handler;
+
+ public AjcConfigParser(AjBuildConfig buildConfig, IMessageHandler handler, boolean incrementalMode) {
+ this.buildConfig = buildConfig;
+ this.handler = handler;
+ this.incrementalArgsMode = incrementalMode;
+ }
+
+ public List getUnparsedArgs() {
+ return unparsedArgs;
+ }
+
+ public void parseOption(String arg, LinkedList args) {
+ int nextArgIndex = args.indexOf(arg)+1;
+ if (arg.equals("-Xlint")) {;
+ buildConfig.getAjOptions().put(
+ AjCompilerOptions.OPTION_Xlint,
+ CompilerOptions.GENERATE);
+ } else if (arg.equals("-injars")) {;
+ if (args.size() > nextArgIndex) {
+ buildConfig.getAjOptions().put(AjCompilerOptions.OPTION_InJARs, CompilerOptions.PRESERVE);
+
+ StringTokenizer st = new StringTokenizer(
+ ((ConfigParser.Arg)args.get(nextArgIndex)).getValue(),
+ File.pathSeparator);
+ while (st.hasMoreTokens()) {
+ String filename = st.nextToken();
+ File jarFile = makeFile(filename);
+ if (filename.endsWith(".jar") && jarFile.exists()) {
+ buildConfig.getInJars().add(jarFile);
+ } else {
+ handler.handleMessage(new Message(
+ "ignoring bad injar: " + filename,
+ Message.WARNING, null, null));
+ }
+ }
+
+ args.remove(args.get(nextArgIndex));
+ }
+ } else if (arg.equals("-aspectpath")) {;
+ if (args.size() > nextArgIndex) {
+ StringTokenizer st = new StringTokenizer(
+ ((ConfigParser.Arg)args.get(nextArgIndex)).getValue(),
+ File.pathSeparator);
+ while (st.hasMoreTokens()) {
+ String filename = st.nextToken();
+ File jarFile = makeFile(filename);
+ if (filename.endsWith(".jar") && jarFile.exists()) {
+ buildConfig.getAspectpath().add(jarFile);
+ } else {
+ handler.handleMessage(new Message(
+ "ignoring bad injar: " + filename,
+ Message.WARNING, null, null));
+ }
+ }
+
+ args.remove(args.get(nextArgIndex));
+ }
+ } else if (arg.equals("-sourceroots")) {
+ if (args.size() > nextArgIndex) {
+ List sourceRoots = new ArrayList();
+ StringTokenizer st = new StringTokenizer(
+ ((ConfigParser.Arg)args.get(nextArgIndex)).getValue(),
+ File.pathSeparator);
+ while (st.hasMoreTokens()) {
+ File f = makeFile(st.nextToken());
+ if (f.isDirectory()) {
+ sourceRoots.add(f);
+ } else {
+ handler.handleMessage(new Message(
+ f.getName() + " is not a file, not adding to sourceroots",
+ Message.WARNING, null, null));
+ }
+ }
+
+
+// if (sourceRoots.size() > 1) {
+// handler.handleMessage(new Message(
+// "can not specify more than one source root (compiler limitation)\n"
+// + "using source root: " + sourceRoots.get(0),
+// Message.WARNING, null, null));
+// } else
+ if (sourceRoots.size() < 1) {
+ out.println("must specify a valid source root in incremental mode");
+ } else {
+ buildConfig.setSourceRoots(sourceRoots);
+ }
+ args.remove(args.get(nextArgIndex));
+ } else {
+ out.println("must specify a valid source root in incremental mode");
+ }
+ } else if (arg.equals("-outjar")) {
+ if (args.size() > nextArgIndex) {
+ buildConfig.getAjOptions().put(AjCompilerOptions.OPTION_OutJAR, CompilerOptions.GENERATE);
+ File jarFile = makeFile(((ConfigParser.Arg)args.get(nextArgIndex)).getValue());
+ if (jarFile.getName().endsWith(".jar")) {
+ try {
+ if (!jarFile.exists()) jarFile.createNewFile();
+ } catch (IOException ioe) {
+ // fail siltenty
+ }
+ buildConfig.setOutputJar(jarFile);
+ } else {
+ out.println("file specified with -outjar is not a valid JAR file, ignoring");
+ buildConfig.setLintSpecFile(null);
+ }
+ args.remove(args.get(nextArgIndex));
+ } else {
+ out.println("must specify a file for -outjar");
+ }
+ } else if (arg.equals("-emacssym")) {
+ buildConfig.setEmacsSymMode(true);
+ buildConfig.setGenerateModelMode(true);
+ } else if (arg.equals("-emacssym")) {
+ buildConfig.setEmacsSymMode(true);
+ buildConfig.setGenerateModelMode(true);
+ } else if (arg.equals("-noweave")) {
+ buildConfig.setNoWeave(true);
+ } else if (arg.equals("-XserializableAspects")) {
+ buildConfig.setXserializableAspects(true);
+ } else if (arg.equals("-Xlintfile")) {
+ if (args.size() > nextArgIndex) {
+ File lintSpecFile = makeFile(((ConfigParser.Arg)args.get(nextArgIndex)).getValue());
+ if (lintSpecFile.exists() && lintSpecFile.getName().endsWith(".properties")) {
+ buildConfig.setLintSpecFile(lintSpecFile);
+ } else {
+ out.println("file specified with -Xlintfile does not exist, ignoring");
+ buildConfig.setLintSpecFile(null);
+ }
+ args.remove(args.get(nextArgIndex));
+ } else {
+ out.println("must specify a file for -outjar");
+ }
+ } else if (arg.startsWith("-Xlint")) {
+ int index = arg.indexOf(":");
+ if (index != -1) {
+ buildConfig.setLintMode(arg.substring(index+1));
+ } else {
+ buildConfig.setLintMode(AjBuildConfig.AJLINT_DEFAULT);
+ }
+ } else if (arg.equals("-bootclasspath")) {
+ if (args.size() > nextArgIndex) {
+ bootclasspath = ((ConfigParser.Arg)args.get(nextArgIndex)).getValue();
+ args.remove(args.get(nextArgIndex));
+ }
+ } else if (arg.equals("-extdirs")) {
+ if (args.size() > nextArgIndex) {
+ extdirs = ((ConfigParser.Arg)args.get(nextArgIndex)).getValue();
+ args.remove(args.get(nextArgIndex));
+ }
+ } else {
+// if (arg.equals("-d")) {
+// int nextArgIndex = args.indexOf(arg)+1;
+// if (args.size() > nextArgIndex) {
+// ConfigParser.Arg path = (ConfigParser.Arg)args.get(nextArgIndex);
+// path.setValue(makeFile(path.getValue()).getPath());
+// }
+// }
+ unparsedArgs.add(arg);
+ }
+ }
+
+ public void showError(String message) {
+// out.println(message);
+ handler.handleMessage(new Message(message, Message.ERROR, null, null));
+ }
+
+
+ protected void showWarning(String message) {
+ handler.handleMessage(new Message(message, Message.WARNING, null, null));
+ }
+
+ }
+}
diff --git a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/ajc/messages.properties b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/ajc/messages.properties
new file mode 100644
index 000000000..3db1d2dc7
--- /dev/null
+++ b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/ajc/messages.properties
@@ -0,0 +1,117 @@
+
+### AspectJ-specific messages
+configure.version = AspectJ Compiler 1.1beta1
+configure.directoryNotExist = invalid option or directory does not exist: {0}
+
+### miscellaneous
+misc.usage = AspectJ Compiler 1.1beta1\n\n\
+ Usage: <options> <source files | directories>\n\n\
+ AspectJ-specific options:\n\
+ -Xlint generate crosscutting-specific warnings\n\
+ -injars <jar 1>;<jar 2>;...;<jar P>\n\
+ -outjar <file> generate a single JAR instead of multiple .class files\n\
+ -incremental persistant incremental compiler, requires -sourceroots\n\
+ -sourceroots <dir> find and build all source files under <dir>;<dir 2>;...\n\n\
+ Standard Eclipse compiler options:\n\
+ -help display this help message\n\
+ -version compiler version number\n\
+ -classpath <dir 1>;<dir 2>;...;<dir P>\n\
+ -d <dir> destination dir (if omitted no pkg structure created)\n\
+ \t-d none no classfile is generated\n\
+ -target <ver> classfile target setting (1.1 or 1.2, default is 1.1)\n\
+ -1.3 set compliance level to 1.3 (default)\n\
+ -1.4 set compliance level to 1.4\n\
+ -source <ver> assertions toggle (1.3 or 1.4, default is 1.3 \n\t\t\tin -1.3 mode and 1.4 in -1.4 mode)\n\
+ -nowarn no warning (equivalent to ''-warn:none'')\n\
+ -warn: <level> set warning level (eg ''-warn:unusedLocals,deprecation'')\n\
+ \tconstructorName warn method with constructor name\n\
+ \tpackageDefaultMethod warn attempt to override package-default method\n\
+ \tdeprecation warn usage of deprecated type or member\n\
+ \tmaskedCatchBlocks warn hidden catch block\n\
+ \tunusedLocals warn on unused local variable (never read)\n\
+ \tunusedArguments warn on unused method argument (never read)\n\
+ \tunusedImports warn on unused imports\n\
+ \tsyntheticAccess warn when performing synthetic access \n\t\t\t\tfor innerclass\n\
+ \tassertIdentifier warn occurrence of ''assert'' used as identifier\n\
+ -deprecation equivalent to -warn:deprecation.\n\
+ -g[:<level>] debug attributes level\n\
+ \t-g all debug info (''-g:lines,vars,source'')\n\
+ \t-g:none no debug info\n\
+ \t-g:[lines,vars,source] selective debug info\n\
+ -preserveAllLocals code gen preserve all local variables (for debug)\n\
+ -noImportError no errors for unresolved imports\n\
+ -encoding specify default source encoding format (custom encoding\n\t\t\tcan also be specifed on\
+ a per file basis by suffixing\n\t\t\teach input source file/folder name with '[encoding]')\n\
+ -log <filename> specify a log file\n\
+ -proceedOnError keep compiling when error, dumping class files with\n\t\t\tproblem methods\n\
+ -verbose print accessed/processed compilation units \n\
+ -referenceInfo compute reference info\n\
+ -progress show progress (only in -log mode)\n\
+ -time display speed information\n\
+ -noExit do not call System.exit(n) at end of compilation\n\t\t\t(n=0 if no error)\n\
+ -repeat <n> repeat compilation process <n> times (perf analysis)\n
+
+##########################################
+### JavaBatchCompiler messages.
+
+### compiler version id
+compiler.version = 0.265
+### scanning
+scanning.start = Collecting source files inside {0}
+
+### progress
+progress.compiling = Compiling
+
+### compile
+compile.repetition = Repetition {0}/{1}
+compile.instantTime = Compiled {0} lines in {1} ms ({2} lines/s)
+compile.totalTime = Total compilation time: {0}
+compile.oneProblem = 1 problem
+compile.severalProblems = {0} problems
+compile.oneError = 1 error
+compile.severalErrors = {0} errors
+compile.oneWarning = 1 warning
+compile.severalWarnings = {0} warnings
+compile.oneClassFileGenerated = 1 .class file generated
+compile.severalClassFilesGenerated = {0} .class files generated
+
+### configure
+configure.noSourceFile = no source file specified
+configure.duplicateLog = duplicate log specification: {0}
+configure.duplicateRepeat = duplicate repeat specification: {0}
+configure.duplicateCompliance = duplicate compliance setting specification: {0}
+configure.source = invalid source option, source is either ''1.3'' or ''1.4'': {0}
+configure.jck = invalid jck option, jck compliance level is either ''1.3'' or ''1.4'': {0}
+configure.duplicateOutputPath = duplicate output path specification: {0}
+configure.duplicateClasspath = duplicate classpath specification: {0}
+configure.invalidDebugOption = invalid debug option: {0}
+configure.duplicateWarningConfiguration = duplicate usage of warning configuration
+configure.invalidWarningConfiguration = invalid warning configuration: {0}
+configure.invalidWarning = invalid warning: {0}
+configure.invalidWarningOption = invalid warning option: {0}
+configure.targetJDK = target JDK should be comprised in between ''1.1'' and ''1.4'': {0}
+configure.incompatibleTargetForSource14 = ''1.4'' source mode requires ''-target 1.4'' : {0}
+configure.incompatibleComplianceForSource14 = ''1.4'' source mode requires ''-1.4'' compliance mode: {0}
+configure.incompatibleComplianceForTarget14 = ''1.4'' target mode requires ''-1.4'' compliance mode: {0}
+configure.repetition = repetition must be a positive integer: {0}
+configure.IOError = i/o error : unable to retrieve .JAVA files in directory: {0}
+configure.noClasspath =
+configure.incorrectClasspath = incorrect classpath: {0}
+configure.noSource = no source file specified
+configure.cannotOpenLog = cannot open .log file
+configure.unexpectedCustomEncoding = unexpected custom encoding specification: {0}[{1}]
+configure.unsupportedEncoding = unsupported encoding format: {0}
+configure.duplicateDefaultEncoding = duplicate default encoding format specification: {0}
+
+### requestor
+requestor.error = ERROR
+requestor.warning = WARNING
+requestor.in = in {0}
+requestor.notRetrieveErrorMessage = Cannot retrieve the error message for {0}
+
+### unit
+unit.more = File {0} is specified more than once
+unit.missing = File {0} is missing
+
+### output
+output.noClassFileCreated = No .class file created for file named {0} because of an IOException.
diff --git a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/compiler/IAjTerminalSymbols.java b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/compiler/IAjTerminalSymbols.java
new file mode 100644
index 000000000..3883dd3d2
--- /dev/null
+++ b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/compiler/IAjTerminalSymbols.java
@@ -0,0 +1,24 @@
+/* *******************************************************************
+ * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC).
+ * All rights reserved.
+ * This program and the accompanying materials are made available
+ * under the terms of the Common Public License v1.0
+ * which accompanies this distribution and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * Xerox/PARC initial implementation
+ * ******************************************************************/
+
+
+package org.aspectj.ajdt.compiler;
+
+import org.eclipse.jdt.core.compiler.ITerminalSymbols;
+
+/**
+ * This should contain a list of symbols unique to AspectJ grammar, but
+ * getting jikespg to do that is too much work right now.
+ */
+public interface IAjTerminalSymbols extends ITerminalSymbols {
+
+}
diff --git a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/AjCompiler.java b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/AjCompiler.java
new file mode 100644
index 000000000..79eb39f4b
--- /dev/null
+++ b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/AjCompiler.java
@@ -0,0 +1,65 @@
+/* *******************************************************************
+ * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC).
+ * All rights reserved.
+ * This program and the accompanying materials are made available
+ * under the terms of the Common Public License v1.0
+ * which accompanies this distribution and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * Xerox/PARC initial implementation
+ * ******************************************************************/
+
+
+package org.aspectj.ajdt.internal.compiler;
+
+import java.util.Map;
+
+import org.aspectj.ajdt.internal.compiler.lookup.EclipseWorld;
+import org.eclipse.jdt.internal.compiler.*;
+import org.eclipse.jdt.internal.compiler.Compiler;
+import org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration;
+import org.eclipse.jdt.internal.compiler.env.INameEnvironment;
+
+
+public class AjCompiler extends Compiler {
+
+ public AjCompiler(
+ INameEnvironment environment,
+ IErrorHandlingPolicy policy,
+ Map settings,
+ ICompilerRequestor requestor,
+ IProblemFactory problemFactory) {
+ super(environment, policy, settings, requestor, problemFactory);
+ }
+
+ public AjCompiler(
+ INameEnvironment environment,
+ IErrorHandlingPolicy policy,
+ Map settings,
+ ICompilerRequestor requestor,
+ IProblemFactory problemFactory,
+ boolean parseLiteralExpressionsAsConstants) {
+ super(
+ environment,
+ policy,
+ settings,
+ requestor,
+ problemFactory,
+ parseLiteralExpressionsAsConstants);
+ }
+
+ /**
+ * In addition to processing each compilation unit in the normal ways,
+ * we also need to do weaving for inter-type declarations. This
+ * must be done before we use the signatures of these types to do any
+ * name binding.
+ */
+ protected void process(CompilationUnitDeclaration unit, int i) {
+ super.process(unit, i);
+
+ EclipseWorld world =
+ EclipseWorld.forLookupEnvironment(lookupEnvironment);
+ world.finishedCompilationUnit(unit);
+ }
+}
diff --git a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/AdviceDeclaration.java b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/AdviceDeclaration.java
new file mode 100644
index 000000000..6e057f6bf
--- /dev/null
+++ b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/AdviceDeclaration.java
@@ -0,0 +1,350 @@
+/* *******************************************************************
+ * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC).
+ * All rights reserved.
+ * This program and the accompanying materials are made available
+ * under the terms of the Common Public License v1.0
+ * which accompanies this distribution and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * Xerox/PARC initial implementation
+ * ******************************************************************/
+
+
+package org.aspectj.ajdt.internal.compiler.ast;
+
+import java.io.*;
+import java.lang.reflect.*;
+import java.util.*;
+
+import org.aspectj.ajdt.internal.compiler.lookup.*;
+import org.aspectj.ajdt.internal.compiler.lookup.AjTypeConstants;
+import org.aspectj.weaver.*;
+//import org.aspectj.weaver.bcel.*;
+import org.eclipse.jdt.internal.compiler.*;
+import org.eclipse.jdt.internal.compiler.CompilationResult;
+import org.eclipse.jdt.internal.compiler.ast.*;
+import org.eclipse.jdt.internal.compiler.codegen.CodeStream;
+import org.eclipse.jdt.internal.compiler.lookup.*;
+import org.eclipse.jdt.internal.compiler.parser.Parser;
+import org.eclipse.jdt.internal.core.util.CharArrayOps;
+
+
+public class AdviceDeclaration extends MethodDeclaration implements IAjDeclaration {
+ public PointcutDesignator pointcutDesignator;
+ int baseArgumentCount;
+
+ public Argument extraArgument;
+
+ public AdviceKind kind; // adviceMunger;
+
+ private int extraArgumentFlags = 0;
+
+ public MethodBinding proceedMethodBinding;
+
+ public AdviceDeclaration(CompilationResult result, AdviceKind kind) {
+ super(result);
+ this.returnType = TypeReference.baseTypeReference(T_void, 0);
+ this.kind = kind;
+ }
+
+
+ protected int generateInfoAttributes(ClassFile classFile) {
+ List l = new ArrayList(1);
+ l.add(new EclipseAttributeAdapter(makeAttribute()));
+
+ return classFile.generateMethodInfoAttribute(binding, l);
+ }
+
+ public AjAttribute makeAttribute() {
+ return new AjAttribute.AdviceAttribute(kind, pointcutDesignator.getPointcut(),
+ extraArgumentFlags, sourceStart, sourceEnd, null);
+ }
+
+ public void resolveStatements(ClassScope upperScope) {
+ if (binding == null || ignoreFurtherInvestigation) return;
+
+ modifiers = binding.modifiers = checkAndSetModifiers(modifiers, upperScope);
+
+
+ pointcutDesignator.finishResolveTypes(this, this.binding,
+ baseArgumentCount, upperScope.referenceContext.binding);
+
+
+ if (kind == AdviceKind.Around && binding != null) {
+ ReferenceBinding[] exceptions =
+ new ReferenceBinding[] { upperScope.getJavaLangThrowable() };
+ proceedMethodBinding = new MethodBinding(Modifier.STATIC,
+ "proceed".toCharArray(), binding.returnType,
+ resize(baseArgumentCount+1, binding.parameters),
+ exceptions, binding.declaringClass);
+ proceedMethodBinding.selector =
+ CharArrayOps.concat(selector, proceedMethodBinding.selector);
+ }
+
+ super.resolveStatements(upperScope);
+ if (binding != null) determineExtraArgumentFlags();
+ }
+
+
+ public int getDeclaredParameterCount() {
+ // this only works before code generation
+ return this.arguments.length - 3 - ((extraArgument == null) ? 0 : 1);
+ //Advice.countOnes(extraArgumentFlags);
+ }
+
+ public void generateProceedMethod(ClassScope classScope, ClassFile classFile) {
+ MethodBinding binding = (MethodBinding)proceedMethodBinding;
+
+ classFile.generateMethodInfoHeader(binding);
+ int methodAttributeOffset = classFile.contentsOffset;
+ int attributeNumber = classFile.generateMethodInfoAttribute(binding, AstUtil.getAjSyntheticAttribute());
+ int codeAttributeOffset = classFile.contentsOffset;
+ classFile.generateCodeAttributeHeader();
+ CodeStream codeStream = classFile.codeStream;
+ codeStream.reset(this, classFile);
+
+ // push the closure
+ int nargs = binding.parameters.length;
+ int closureIndex = 0;
+ for (int i=0; i < nargs-1; i++) {
+ closureIndex += AstUtil.slotsNeeded(binding.parameters[i]);
+ }
+
+
+ codeStream.loadObject(closureIndex);
+
+ // build the Object[]
+
+ codeStream.generateInlinedValue(nargs-1);
+ codeStream.anewarrayJavaLangObject();
+
+ int index = 0;
+ for (int i=0; i < nargs-1; i++) {
+ TypeBinding type = binding.parameters[i];
+ codeStream.dup();
+ codeStream.generateInlinedValue(i);
+ codeStream.load(type, index);
+ index += AstUtil.slotsNeeded(type);
+ if (type.isBaseType()) {
+ codeStream.invokestatic(AjTypeConstants.getConversionMethodToObject(classScope, type));
+ }
+
+ codeStream.aastore();
+ }
+
+ // call run
+ ReferenceBinding closureType = (ReferenceBinding)binding.parameters[nargs-1];
+ MethodBinding runMethod = closureType.getMethods("run".toCharArray())[0];
+ codeStream.invokevirtual(runMethod);
+
+ TypeBinding returnType = binding.returnType;
+ if (returnType.isBaseType()) {
+ codeStream.invokestatic(AjTypeConstants.getConversionMethodFromObject(classScope, returnType));
+ } else {
+ codeStream.checkcast(returnType);
+ }
+ AstUtil.generateReturn(returnType, codeStream);
+
+ classFile.completeCodeAttribute(codeAttributeOffset);
+ attributeNumber++;
+ classFile.completeMethodInfo(methodAttributeOffset, attributeNumber);
+ }
+
+
+
+ public void generateCode(ClassScope classScope, ClassFile classFile) {
+ if (proceedMethodBinding != null) {
+// MethodDeclaration dec =
+// AstUtil.makeMethodDeclaration(proceedMethodBinding);
+//
+// List stmts = new ArrayList();
+//
+// Expression expr = AstUtil.makeLocalVariableReference(dec.arguments[0].binding);
+//
+//
+// stmts.add(AstUtil.makeReturnStatement(expr));
+//
+// AstUtil.setStatements(dec, stmts);
+// dec.scope = this.scope;
+// dec.generateCode(classScope, classFile);
+ }
+ super.generateCode(classScope, classFile);
+ if (proceedMethodBinding != null) {
+ generateProceedMethod(classScope, classFile);
+ }
+ }
+
+
+ private void determineExtraArgumentFlags() {
+ if (extraArgument != null) extraArgumentFlags |= Advice.ExtraArgument;
+
+ ThisJoinPointVisitor tjp = new ThisJoinPointVisitor(this);
+ extraArgumentFlags |= tjp.removeUnusedExtraArguments();
+ }
+
+ private static TypeBinding[] resize(int newSize, TypeBinding[] bindings) {
+ int len = bindings.length;
+ TypeBinding[] ret = new TypeBinding[newSize];
+ System.arraycopy(bindings, 0, ret, 0, Math.min(newSize, len));
+ return ret;
+ }
+
+
+
+ public void finishParsing() {
+ //kind = AdviceKind.stringToKind(new String(selector));
+ //System.out.println(this + " kind " + kind + " name " + new String(selector));
+ //selector = ("ajc_" + kind.toString() + "_" + Integer.toHexString(position)).toCharArray();
+ //System.out.println(this + " kind " + kind + " name " + new String(selector));
+
+ if (arguments != null) {
+ baseArgumentCount = arguments.length;
+ }
+
+ if (kind == AdviceKind.Around) {
+ extraArgument = makeFinalArgument("ajc_aroundClosure",
+ AjTypeConstants.getAroundClosureType());
+ }
+
+ int addedArguments = 3;
+ if (extraArgument != null) {
+ addedArguments += 1;
+ }
+
+ arguments = extendArgumentsLength(arguments, addedArguments);
+
+ int index = baseArgumentCount;
+ if (extraArgument != null) {
+ arguments[index++] = extraArgument;
+ }
+
+ arguments[index++] = makeFinalArgument("thisJoinPointStaticPart", AjTypeConstants.getJoinPointStaticPartType());
+ arguments[index++] = makeFinalArgument("thisJoinPoint", AjTypeConstants.getJoinPointType());
+ arguments[index++] = makeFinalArgument("thisEnclosingJoinPointStaticPart", AjTypeConstants.getJoinPointStaticPartType());
+
+ //modifiers = checkAndSetModifiers(modifiers);
+
+ if (pointcutDesignator.isError()) {
+ //System.err.println("ignoring further investigation for: " + this);
+ this.ignoreFurtherInvestigation = true;
+ }
+
+
+ }
+
+ private int checkAndSetModifiers(int modifiers, ClassScope scope) {
+ if (modifiers == 0) return Modifier.PUBLIC;
+ else if (modifiers == Modifier.STRICT) return Modifier.PUBLIC | Modifier.STRICT;
+ else {
+ tagAsHavingErrors();
+ scope.problemReporter().signalError(declarationSourceStart, sourceStart-1, "illegal modifier on advice, only strictfp is allowed");
+ return Modifier.PUBLIC;
+ }
+ }
+
+
+ public static Argument[] addTjpArguments(Argument[] arguments) {
+ int index = arguments.length;
+ arguments = extendArgumentsLength(arguments, 3);
+
+ arguments[index++] = makeFinalArgument("thisJoinPointStaticPart", AjTypeConstants.getJoinPointStaticPartType());
+ arguments[index++] = makeFinalArgument("thisJoinPoint", AjTypeConstants.getJoinPointType());
+ arguments[index++] = makeFinalArgument("thisEnclosingJoinPointStaticPart", AjTypeConstants.getJoinPointStaticPartType());
+
+ return arguments;
+ }
+
+
+
+ private static Argument makeFinalArgument(String name, TypeReference typeRef) {
+ long pos = 0; //XXX encode start and end location
+ return new Argument(name.toCharArray(), pos, typeRef, Modifier.FINAL);
+ }
+
+
+ private static Argument[] extendArgumentsLength(Argument[] args, int addedArguments) {
+ if (args == null) {
+ return new Argument[addedArguments];
+ }
+ int len = args.length;
+ Argument[] ret = new Argument[len + addedArguments];
+ System.arraycopy(args, 0, ret, 0, len);
+ return ret;
+ }
+
+
+ public String toString(int tab) {
+ String s = tabString(tab);
+ if (modifiers != AccDefault) {
+ s += modifiersString(modifiers);
+ }
+
+ if (kind == AdviceKind.Around) {
+ s += returnTypeToString(0);
+ }
+
+ s += new String(selector) + "("; //$NON-NLS-1$
+ if (arguments != null) {
+ for (int i = 0; i < arguments.length; i++) {
+ s += arguments[i].toString(0);
+ if (i != (arguments.length - 1))
+ s = s + ", "; //$NON-NLS-1$
+ };
+ };
+ s += ")"; //$NON-NLS-1$
+
+ if (extraArgument != null) {
+ s += "(" + extraArgument.toString(0) + ")";
+ }
+
+
+
+ if (thrownExceptions != null) {
+ s += " throws "; //$NON-NLS-1$
+ for (int i = 0; i < thrownExceptions.length; i++) {
+ s += thrownExceptions[i].toString(0);
+ if (i != (thrownExceptions.length - 1))
+ s = s + ", "; //$NON-NLS-1$
+ };
+ };
+
+ s += ": ";
+ if (pointcutDesignator != null) {
+ s += pointcutDesignator.toString(0);
+ }
+
+ s += toStringStatements(tab + 1);
+ return s;
+ }
+
+ public void modifyKind(char[] name) {
+ this.selector = CharArrayOps.concat(selector, name);
+ }
+
+// public boolean finishResolveTypes(SourceTypeBinding sourceTypeBinding) {
+// if (this.ignoreFurtherInvestigation) {
+// return false;
+// }
+//
+// if ((binding.modifiers & AccUnresolved) == 0) return true;
+//
+// //System.err.println("this " + this + ", " + binding.modifiers);
+// binding.modifiers ^= AccUnresolved;
+// //System.err.println(" post " + binding.modifiers);
+//
+//
+// return super.finishResolveTypes(sourceTypeBinding) &&
+// pointcutDesignator.finishResolveTypes(this, this.binding, baseArgumentCount, sourceTypeBinding)
+// ;
+// }
+
+
+ public void postParse(TypeDeclaration typeDec) {
+ this.selector =
+ NameMangler.adviceName(EclipseWorld.fromBinding(typeDec.binding), kind, sourceStart).toCharArray();
+ finishParsing();
+ pointcutDesignator.postParse(typeDec, this);
+ }
+
+}
diff --git a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/AspectClinit.java b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/AspectClinit.java
new file mode 100644
index 000000000..d1e77d4c2
--- /dev/null
+++ b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/AspectClinit.java
@@ -0,0 +1,48 @@
+/* *******************************************************************
+ * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC).
+ * All rights reserved.
+ * This program and the accompanying materials are made available
+ * under the terms of the Common Public License v1.0
+ * which accompanies this distribution and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * Xerox/PARC initial implementation
+ * ******************************************************************/
+
+
+package org.aspectj.ajdt.internal.compiler.ast;
+
+import org.aspectj.ajdt.internal.compiler.lookup.EclipseWorld;
+import org.aspectj.weaver.AjcMemberMaker;
+import org.eclipse.jdt.internal.compiler.CompilationResult;
+import org.eclipse.jdt.internal.compiler.ast.Clinit;
+import org.eclipse.jdt.internal.compiler.codegen.CodeStream;
+import org.eclipse.jdt.internal.compiler.lookup.ClassScope;
+
+public class AspectClinit extends Clinit {
+ public AspectClinit(Clinit old, CompilationResult compilationResult) {
+ super(compilationResult);
+ this.needFreeReturn = old.needFreeReturn;
+ this.sourceEnd = old.sourceEnd;
+ this.sourceStart = old.sourceStart;
+ this.declarationSourceEnd = old.declarationSourceEnd;
+ this.declarationSourceStart = old.declarationSourceStart;
+ }
+
+ protected void generateSyntheticCode(
+ ClassScope classScope,
+ CodeStream codeStream)
+ {
+ if (!classScope.referenceContext.binding.isAbstract()) {
+ final EclipseWorld world = EclipseWorld.fromScopeLookupEnvironment(classScope);
+
+ codeStream.invokestatic(world.makeMethodBindingForCall(
+ AjcMemberMaker.ajcClinitMethod(
+ world.fromBinding(classScope.referenceContext.binding)
+ )));
+ }
+ super.generateSyntheticCode(classScope, codeStream);
+ }
+
+}
diff --git a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/AspectDeclaration.java b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/AspectDeclaration.java
new file mode 100644
index 000000000..ef48a39db
--- /dev/null
+++ b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/AspectDeclaration.java
@@ -0,0 +1,705 @@
+/* *******************************************************************
+ * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC).
+ * All rights reserved.
+ * This program and the accompanying materials are made available
+ * under the terms of the Common Public License v1.0
+ * which accompanies this distribution and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * Xerox/PARC initial implementation
+ * ******************************************************************/
+
+
+package org.aspectj.ajdt.internal.compiler.ast;
+
+import java.io.*;
+import java.lang.reflect.Modifier;
+
+import org.apache.bcel.classfile.AccessFlags;
+import org.aspectj.ajdt.internal.compiler.lookup.*;
+import org.aspectj.ajdt.internal.compiler.lookup.EclipseWorld;
+import org.aspectj.weaver.*;
+import org.aspectj.weaver.AjAttribute;
+import org.aspectj.weaver.patterns.*;
+import org.eclipse.jdt.internal.compiler.*;
+import org.eclipse.jdt.internal.compiler.ast.*;
+import org.eclipse.jdt.internal.compiler.codegen.*;
+import org.eclipse.jdt.internal.compiler.codegen.CodeStream;
+import org.eclipse.jdt.internal.compiler.lookup.*;
+import org.eclipse.jdt.internal.compiler.lookup.ClassScope;
+
+
+// making all aspects member types avoids a nasty hierarchy pain
+public class AspectDeclaration extends MemberTypeDeclaration {
+ //public IAjDeclaration[] ajDeclarations;
+
+ private AjAttribute.Aspect aspectAttribute;
+ public PerClause perClause;
+ public ResolvedMember aspectOfMethod;
+ public ResolvedMember hasAspectMethod;
+
+
+ public boolean isPrivileged;
+
+ public EclipseObjectType typeX;
+ public EclipseWorld world; //??? should use this consistently
+
+
+ // for better error messages in 1.0 to 1.1 transition
+ public TypePattern dominatesPattern;
+
+ public AspectDeclaration(CompilationResult compilationResult) {
+ super(compilationResult);
+ //perClause = new PerSingleton();
+ }
+
+ public boolean isAbstract() {
+ return (modifiers & AccAbstract) != 0;
+ }
+
+ public void checkSpec(ClassScope scope) {
+ if (ignoreFurtherInvestigation) return;
+ if (dominatesPattern != null) {
+ scope.problemReporter().signalError(
+ dominatesPattern.getStart(), dominatesPattern.getEnd(),
+ "dominates has changed for 1.1, use 'declare dominates: " +
+ new String(this.name) + ", " + dominatesPattern.toString() + ";' " +
+ "in the body of the aspect instead");
+ }
+
+ if (!isAbstract()) {
+ MethodBinding[] methods = binding.methods();
+ for (int i=0, len = methods.length; i < len; i++) {
+ MethodBinding m = methods[i];
+ if (m.isConstructor()) {
+ // this make all constructors in aspects invisible and thus uncallable
+ //XXX this only works for aspects that come from source
+ methods[i] = new MethodBinding(m, binding) {
+ public boolean canBeSeenBy(
+ InvocationSite invocationSite,
+ Scope scope) {
+ return false;
+ }
+ };
+
+ if (m.parameters != null && m.parameters.length != 0) {
+ scope.problemReporter().signalError(m.sourceStart(), m.sourceEnd(),
+ "only zero-argument constructors allowed in concrete aspect");
+ }
+ }
+ }
+ }
+
+ if (this.enclosingType != null) {
+ if (!Modifier.isStatic(modifiers)) {
+ scope.problemReporter().signalError(sourceStart, sourceEnd,
+ "inner aspects must be static");
+ ignoreFurtherInvestigation = true;
+ return;
+ }
+ }
+
+
+ EclipseWorld world = EclipseWorld.fromScopeLookupEnvironment(scope);
+ ResolvedTypeX myType = world.fromEclipse(binding);
+ ResolvedTypeX superType = myType.getSuperclass().resolve(world);
+
+ // can't be Serializable/Cloneable unless -XserializableAspects
+ if (!world.buildManager.buildConfig.isXserializableAspects()) {
+ if (world.resolve(TypeX.SERIALIZABLE).isAssignableFrom(myType)) {
+ scope.problemReporter().signalError(sourceStart, sourceEnd,
+ "aspects may not implement Serializable");
+ ignoreFurtherInvestigation = true;
+ return;
+ }
+ if (world.resolve(TypeX.CLONEABLE).isAssignableFrom(myType)) {
+ scope.problemReporter().signalError(sourceStart, sourceEnd,
+ "aspects may not implement Cloneable");
+ ignoreFurtherInvestigation = true;
+ return;
+ }
+
+ }
+
+
+
+ if (superType.isAspect()) {
+ if (!superType.isAbstract()) {
+ scope.problemReporter().signalError(sourceStart, sourceEnd,
+ "can not extend a concrete aspect");
+ ignoreFurtherInvestigation = true;
+ return;
+ }
+ }
+
+ //XXX need to move this somewhere that it will be applied to classes and interfaces
+ // as well as to aspects, also need to handle inheritance and overriding
+// ResolvedMember[] pointcuts = myType.getDeclaredPointcuts();
+// for (int i=0, len=pointcuts.length; i < len; i++) {
+// for (int j=i+1; j < len; j++) {
+// if (pointcuts[i].getName().equals(pointcuts[j].getName())) {
+// scope.problemReporter().signalError(0, 0,
+// "duplicate pointcut name: " + pointcuts[i].getName());
+// }
+// }
+// }
+ }
+
+
+
+ public void generateCode(ClassFile enclosingClassFile) {
+ if (ignoreFurtherInvestigation) {
+ if (binding == null)
+ return;
+ ClassFile.createProblemType(
+ this,
+ scope.referenceCompilationUnit().compilationResult);
+ return;
+ }
+
+
+ // make me and my binding public
+ this.modifiers = AstUtil.makePublic(this.modifiers);
+ this.binding.modifiers = AstUtil.makePublic(this.binding.modifiers);
+
+
+ if (!isAbstract()) {
+ if (perClause == null) {
+ // we've already produced an error for this
+ } else if (perClause.getKind() == PerClause.SINGLETON) {
+ binding.addField(world.makeFieldBinding(AjcMemberMaker.perSingletonField(
+ typeX)));
+ methods[0] = new AspectClinit((Clinit)methods[0], compilationResult);
+ } else if (perClause.getKind() == PerClause.PERCFLOW) {
+ binding.addField(
+ world.makeFieldBinding(
+ AjcMemberMaker.perCflowField(
+ typeX)));
+ methods[0] = new AspectClinit((Clinit)methods[0], compilationResult);
+ } else if (perClause.getKind() == PerClause.PEROBJECT) {
+// binding.addField(
+// world.makeFieldBinding(
+// AjcMemberMaker.perCflowField(
+// typeX)));
+ } else {
+ throw new RuntimeException("unimplemented");
+ }
+ }
+
+ if (EclipseWorld.DEBUG) System.out.println(toString(0));
+
+ super.generateCode(enclosingClassFile);
+ }
+
+ public boolean needClassInitMethod() {
+ return true;
+ }
+
+
+ protected void generateAttributes(ClassFile classFile) {
+ if (!isAbstract()) generatePerSupportMembers(classFile);
+
+ classFile.extraAttributes.add(
+ new EclipseAttributeAdapter(new AjAttribute.Aspect(perClause)));
+
+ if (binding.privilegedHandler != null) {
+ ResolvedMember[] members = ((PrivilegedHandler)binding.privilegedHandler).getMembers();
+ classFile.extraAttributes.add(
+ new EclipseAttributeAdapter(new AjAttribute.PrivilegedAttribute(members)));
+ }
+
+ //XXX need to get this attribute on anyone with a pointcut for good errors
+ classFile.extraAttributes.add(
+ new EclipseAttributeAdapter(new AjAttribute.SourceContextAttribute(
+ new String(compilationResult().getFileName()),
+ compilationResult().lineSeparatorPositions)));
+
+ super.generateAttributes(classFile);
+ }
+
+ private void generatePerSupportMembers(ClassFile classFile) {
+ if (isAbstract()) return;
+
+ //XXX otherwise we need to have this (error handling?)
+ if (aspectOfMethod == null) return;
+ if (perClause == null) {
+ System.err.println("has null perClause: " + this);
+ return;
+ }
+
+ EclipseWorld world = EclipseWorld.fromScopeLookupEnvironment(this.scope);
+
+ if (perClause.getKind() == PerClause.SINGLETON) {
+ generatePerSingletonAspectOfMethod(classFile);
+ generatePerSingletonHasAspectMethod(classFile);
+ generatePerSingletonAjcClinitMethod(classFile);
+ } else if (perClause.getKind() == PerClause.PERCFLOW) {
+ generatePerCflowAspectOfMethod(classFile);
+ generatePerCflowHasAspectMethod(classFile);
+ generatePerCflowPushMethod(classFile);
+ generatePerCflowAjcClinitMethod(classFile);
+ } else if (perClause.getKind() == PerClause.PEROBJECT) {
+ TypeBinding interfaceType =
+ generatePerObjectInterface(classFile);
+ world.addTypeBinding(interfaceType);
+ generatePerObjectAspectOfMethod(classFile, interfaceType);
+ generatePerObjectHasAspectMethod(classFile, interfaceType);
+ generatePerObjectBindMethod(classFile, interfaceType);
+ } else {
+ throw new RuntimeException("unimplemented");
+ }
+ }
+
+
+ private static interface BodyGenerator {
+ public void generate(CodeStream codeStream);
+ }
+
+
+ private void generateMethod(ClassFile classFile, ResolvedMember member, BodyGenerator gen) {
+ final EclipseWorld world = EclipseWorld.fromScopeLookupEnvironment(this.scope);
+ generateMethod(classFile, world.makeMethodBinding(member), gen);
+ }
+
+ private void generateMethod(ClassFile classFile, MethodBinding methodBinding, BodyGenerator gen) {
+ EclipseWorld world = EclipseWorld.fromScopeLookupEnvironment(this.scope);
+ classFile.generateMethodInfoHeader(methodBinding);
+ int methodAttributeOffset = classFile.contentsOffset;
+ int attributeNumber = classFile.generateMethodInfoAttribute(methodBinding, AstUtil.getAjSyntheticAttribute());
+ int codeAttributeOffset = classFile.contentsOffset;
+ classFile.generateCodeAttributeHeader();
+ CodeStream codeStream = classFile.codeStream;
+ codeStream.init(classFile);
+ codeStream.initializeMaxLocals(methodBinding);
+ // body starts here
+ gen.generate(codeStream);
+ // body ends here
+ classFile.completeCodeAttribute(codeAttributeOffset);
+ attributeNumber++;
+ classFile.completeMethodInfo(methodAttributeOffset, attributeNumber);
+ }
+
+
+ private void generatePerCflowAspectOfMethod(
+ ClassFile classFile)
+ {
+ final EclipseWorld world = EclipseWorld.fromScopeLookupEnvironment(this.scope);
+ generateMethod(classFile, aspectOfMethod, new BodyGenerator() {
+ public void generate(CodeStream codeStream) {
+ // body starts here
+ codeStream.getstatic(
+ world.makeFieldBinding(
+ AjcMemberMaker.perCflowField(
+ typeX)));
+ codeStream.invokevirtual(world.makeMethodBindingForCall(
+ AjcMemberMaker.cflowStackPeekInstance()));
+ codeStream.checkcast(binding);
+ codeStream.areturn();
+ // body ends here
+ }});
+
+ }
+
+
+ private void generatePerCflowHasAspectMethod(ClassFile classFile) {
+ final EclipseWorld world = EclipseWorld.fromScopeLookupEnvironment(this.scope);
+ generateMethod(classFile, hasAspectMethod, new BodyGenerator() {
+ public void generate(CodeStream codeStream) {
+ // body starts here
+ codeStream.getstatic(
+ world.makeFieldBinding(
+ AjcMemberMaker.perCflowField(
+ typeX)));
+ codeStream.invokevirtual(world.makeMethodBindingForCall(
+ AjcMemberMaker.cflowStackIsValid()));
+ codeStream.ireturn();
+ // body ends here
+ }});
+ }
+
+ private void generatePerCflowPushMethod(
+ ClassFile classFile)
+ {
+ final EclipseWorld world = EclipseWorld.fromScopeLookupEnvironment(this.scope);
+ generateMethod(classFile, world.makeMethodBinding(AjcMemberMaker.perCflowPush(
+ world.fromBinding(binding))),
+ new BodyGenerator() {
+ public void generate(CodeStream codeStream) {
+ // body starts here
+ codeStream.getstatic(
+ world.makeFieldBinding(
+ AjcMemberMaker.perCflowField(
+ typeX)));
+ codeStream.new_(binding);
+ codeStream.dup();
+ codeStream.invokespecial(
+ new MethodBinding(0, "<init>".toCharArray(),
+ BaseTypes.VoidBinding, new TypeBinding[0],
+ new ReferenceBinding[0], binding));
+
+
+ codeStream.invokevirtual(world.makeMethodBindingForCall(
+ AjcMemberMaker.cflowStackPushInstance()));
+ codeStream.return_();
+ // body ends here
+ }});
+
+ }
+
+
+
+
+ private void generatePerCflowAjcClinitMethod(
+ ClassFile classFile)
+ {
+ final EclipseWorld world = EclipseWorld.fromScopeLookupEnvironment(this.scope);
+ generateMethod(classFile, world.makeMethodBinding(AjcMemberMaker.ajcClinitMethod(
+ world.fromBinding(binding))),
+ new BodyGenerator() {
+ public void generate(CodeStream codeStream) {
+ // body starts here
+ codeStream.new_(world.makeTypeBinding(AjcMemberMaker.CFLOW_STACK_TYPE));
+ codeStream.dup();
+ codeStream.invokespecial(world.makeMethodBindingForCall(AjcMemberMaker.cflowStackInit()));
+ codeStream.putstatic(
+ world.makeFieldBinding(
+ AjcMemberMaker.perCflowField(
+ typeX)));
+ codeStream.return_();
+ // body ends here
+ }});
+
+ }
+
+
+ private TypeBinding generatePerObjectInterface(
+ ClassFile classFile)
+ {
+ final EclipseWorld world = EclipseWorld.fromScopeLookupEnvironment(this.scope);
+ TypeX interfaceTypeX =
+ AjcMemberMaker.perObjectInterfaceType(typeX);
+ HelperInterfaceBinding interfaceType =
+ new HelperInterfaceBinding(this.binding, interfaceTypeX);
+ world.addTypeBinding(interfaceType);
+ interfaceType.addMethod(world, AjcMemberMaker.perObjectInterfaceGet(typeX));
+ interfaceType.addMethod(world, AjcMemberMaker.perObjectInterfaceSet(typeX));
+ interfaceType.generateClass(compilationResult, classFile);
+ return interfaceType;
+ }
+
+
+ private void generatePerObjectAspectOfMethod(
+ ClassFile classFile,
+ final TypeBinding interfaceType)
+ {
+ final EclipseWorld world = EclipseWorld.fromScopeLookupEnvironment(this.scope);
+ generateMethod(classFile, aspectOfMethod, new BodyGenerator() {
+ public void generate(CodeStream codeStream) {
+ // body starts here
+ Label wrongType = new Label(codeStream);
+ Label popWrongType = new Label(codeStream);
+ codeStream.aload_0();
+ codeStream.instance_of(interfaceType);
+ codeStream.ifeq(wrongType);
+ codeStream.aload_0();
+ codeStream.checkcast(interfaceType);
+ codeStream.invokeinterface(world.makeMethodBindingForCall(
+ AjcMemberMaker.perObjectInterfaceGet(typeX)));
+
+ codeStream.dup();
+ codeStream.ifnull(popWrongType);
+ codeStream.areturn();
+
+ popWrongType.place();
+ codeStream.pop();
+
+ wrongType.place();
+ codeStream.new_(world.makeTypeBinding(AjcMemberMaker.NO_ASPECT_BOUND_EXCEPTION));
+ codeStream.dup();
+ codeStream.invokespecial(world.makeMethodBindingForCall(
+ AjcMemberMaker.noAspectBoundExceptionInit()
+ ));
+ codeStream.athrow();
+ // body ends here
+ }});
+
+ }
+
+
+ private void generatePerObjectHasAspectMethod(ClassFile classFile,
+ final TypeBinding interfaceType) {
+ final EclipseWorld world = EclipseWorld.fromScopeLookupEnvironment(this.scope);
+ generateMethod(classFile, hasAspectMethod, new BodyGenerator() {
+ public void generate(CodeStream codeStream) {
+ // body starts here
+ Label wrongType = new Label(codeStream);
+ codeStream.aload_0();
+ codeStream.instance_of(interfaceType);
+ codeStream.ifeq(wrongType);
+ codeStream.aload_0();
+ codeStream.checkcast(interfaceType);
+ codeStream.invokeinterface(world.makeMethodBindingForCall(
+ AjcMemberMaker.perObjectInterfaceGet(typeX)));
+ codeStream.ifnull(wrongType);
+ codeStream.iconst_1();
+ codeStream.ireturn();
+
+ wrongType.place();
+ codeStream.iconst_0();
+ codeStream.ireturn();
+ // body ends here
+ }});
+ }
+
+ private void generatePerObjectBindMethod(
+ ClassFile classFile,
+ final TypeBinding interfaceType)
+ {
+ final EclipseWorld world = EclipseWorld.fromScopeLookupEnvironment(this.scope);
+ generateMethod(classFile, AjcMemberMaker.perObjectBind(world.fromBinding(binding)),
+ new BodyGenerator() {
+ public void generate(CodeStream codeStream) {
+ // body starts here
+ Label wrongType = new Label(codeStream);
+ codeStream.aload_0();
+ codeStream.instance_of(interfaceType);
+ codeStream.ifeq(wrongType); //XXX this case might call for screaming
+ codeStream.aload_0();
+ codeStream.checkcast(interfaceType);
+ codeStream.invokeinterface(world.makeMethodBindingForCall(
+ AjcMemberMaker.perObjectInterfaceGet(typeX)));
+ //XXX should do a check for null here and throw a NoAspectBound
+ codeStream.ifnonnull(wrongType);
+
+ codeStream.aload_0();
+ codeStream.checkcast(interfaceType);
+ codeStream.new_(binding);
+ codeStream.dup();
+ codeStream.invokespecial(
+ new MethodBinding(0, "<init>".toCharArray(),
+ BaseTypes.VoidBinding, new TypeBinding[0],
+ new ReferenceBinding[0], binding));
+ codeStream.invokeinterface(world.makeMethodBindingForCall(
+ AjcMemberMaker.perObjectInterfaceSet(typeX)));
+
+ wrongType.place();
+ codeStream.return_();
+ // body ends here
+ }});
+ }
+
+
+
+ private void generatePerSingletonAspectOfMethod(ClassFile classFile) {
+ final EclipseWorld world = EclipseWorld.fromScopeLookupEnvironment(this.scope);
+ generateMethod(classFile, aspectOfMethod, new BodyGenerator() {
+ public void generate(CodeStream codeStream) {
+ // body starts here
+ codeStream.getstatic(world.makeFieldBinding(AjcMemberMaker.perSingletonField(
+ typeX)));
+ codeStream.areturn();
+ // body ends here
+ }});
+ }
+
+ private void generatePerSingletonHasAspectMethod(ClassFile classFile) {
+ final EclipseWorld world = EclipseWorld.fromScopeLookupEnvironment(this.scope);
+ generateMethod(classFile, hasAspectMethod, new BodyGenerator() {
+ public void generate(CodeStream codeStream) {
+ // body starts here
+ codeStream.getstatic(world.makeFieldBinding(AjcMemberMaker.perSingletonField(
+ typeX)));
+ Label isNull = new Label(codeStream);
+ codeStream.ifnull(isNull);
+ codeStream.iconst_1();
+ codeStream.ireturn();
+ isNull.place();
+ codeStream.iconst_0();
+ codeStream.ireturn();
+ // body ends here
+ }});
+ }
+
+
+ private void generatePerSingletonAjcClinitMethod(
+ ClassFile classFile)
+ {
+ final EclipseWorld world = EclipseWorld.fromScopeLookupEnvironment(this.scope);
+ generateMethod(classFile, world.makeMethodBinding(AjcMemberMaker.ajcClinitMethod(
+ world.fromBinding(binding))),
+ new BodyGenerator() {
+ public void generate(CodeStream codeStream) {
+ // body starts here
+ codeStream.new_(binding);
+ codeStream.dup();
+ codeStream.invokespecial(
+ new MethodBinding(0, "<init>".toCharArray(),
+ BaseTypes.VoidBinding, new TypeBinding[0],
+ new ReferenceBinding[0], binding));
+
+ codeStream.putstatic(
+ world.makeFieldBinding(
+ AjcMemberMaker.perSingletonField(
+ typeX)));
+ codeStream.return_();
+ // body ends here
+ }});
+
+ }
+
+
+ private PerClause.Kind lookupPerClauseKind(ReferenceBinding binding) {
+ if (binding instanceof SourceTypeBinding) {
+ SourceTypeBinding sourceSc = (SourceTypeBinding)binding;
+ if (sourceSc.scope.referenceContext instanceof AspectDeclaration) {
+ PerClause perClause = ((AspectDeclaration)sourceSc.scope.referenceContext).perClause;
+ if (perClause == null) return lookupPerClauseKind(binding.superclass());
+ else return perClause.getKind();
+ } else {
+ return null;
+ }
+ } else {
+ //XXX need to handle this too
+ return null;
+ }
+ }
+
+
+ private void buildPerClause(ClassScope scope) {
+ EclipseWorld world = EclipseWorld.fromScopeLookupEnvironment(scope);
+
+ if (perClause == null) {
+ PerClause.Kind kind = lookupPerClauseKind(binding.superclass);
+ if (kind == null) {
+ perClause = new PerSingleton();
+ } else {
+ perClause = new PerFromSuper(kind);
+ }
+ }
+
+
+ //perClause.concretize(world.fromEclipse(binding));
+ aspectAttribute = new AjAttribute.Aspect(perClause);
+
+ if (ignoreFurtherInvestigation) return; //???
+
+
+ if (!isAbstract()) {
+ if (perClause.getKind() == PerClause.SINGLETON) {
+ aspectOfMethod = AjcMemberMaker.perSingletonAspectOfMethod(typeX);
+ hasAspectMethod = AjcMemberMaker.perSingletonHasAspectMethod(typeX);
+ } else if (perClause.getKind() == PerClause.PERCFLOW) {
+ aspectOfMethod = AjcMemberMaker.perCflowAspectOfMethod(typeX);
+ hasAspectMethod = AjcMemberMaker.perCflowHasAspectMethod(typeX);
+ } else if (perClause.getKind() == PerClause.PEROBJECT) {
+ aspectOfMethod = AjcMemberMaker.perObjectAspectOfMethod(typeX);
+ hasAspectMethod = AjcMemberMaker.perObjectHasAspectMethod(typeX);
+ } else {
+ throw new RuntimeException("bad per clause: " + perClause);
+ }
+
+ binding.addMethod(world.makeMethodBinding(aspectOfMethod));
+ binding.addMethod(world.makeMethodBinding(hasAspectMethod));
+ }
+ resolvePerClause(); //XXX might be too soon for some error checking
+ }
+
+
+ private PerClause resolvePerClause() {
+ EclipseScope iscope = new EclipseScope(new FormalBinding[0], scope);
+ perClause.resolve(iscope);
+ return perClause;
+ }
+
+
+
+ public void buildInterTypeAndPerClause(ClassScope classScope) {
+ checkSpec(classScope);
+ if (ignoreFurtherInvestigation) return;
+
+ world = EclipseWorld.fromScopeLookupEnvironment(scope);
+ typeX = (EclipseObjectType)world.fromEclipse(binding);
+
+ if (isPrivileged) {
+ binding.privilegedHandler = new PrivilegedHandler(this);
+ }
+
+ CrosscuttingMembers xcut = new CrosscuttingMembers(typeX);
+ typeX.crosscuttingMembers = xcut;
+ //XXXxcut.setPerClause(buildPerClause(scope));
+ buildPerClause(scope);
+
+ if (methods != null) {
+ for (int i = 0; i < methods.length; i++) {
+ if (methods[i] instanceof InterTypeDeclaration) {
+ ((InterTypeDeclaration)methods[i]).build(classScope, xcut);
+ } else if (methods[i] instanceof DeclareDeclaration) {
+ ((DeclareDeclaration)methods[i]).build(classScope, xcut);
+ }
+ }
+ }
+
+ world.getCrosscuttingMembersSet().addOrReplaceAspect(typeX);
+ }
+
+
+ public String toString(int tab) {
+ return tabString(tab) + toStringHeader() + toStringBody(tab);
+ }
+
+ public String toStringBody(int tab) {
+
+ String s = " {"; //$NON-NLS-1$
+
+
+ if (memberTypes != null) {
+ for (int i = 0; i < memberTypes.length; i++) {
+ if (memberTypes[i] != null) {
+ s += "\n" + memberTypes[i].toString(tab + 1); //$NON-NLS-1$
+ }
+ }
+ }
+ if (fields != null) {
+ for (int fieldI = 0; fieldI < fields.length; fieldI++) {
+ if (fields[fieldI] != null) {
+ s += "\n" + fields[fieldI].toString(tab + 1); //$NON-NLS-1$
+ if (fields[fieldI].isField())
+ s += ";"; //$NON-NLS-1$
+ }
+ }
+ }
+ if (methods != null) {
+ for (int i = 0; i < methods.length; i++) {
+ if (methods[i] != null) {
+ s += "\n" + methods[i].toString(tab + 1); //$NON-NLS-1$
+ }
+ }
+ }
+ s += "\n" + tabString(tab) + "}"; //$NON-NLS-2$ //$NON-NLS-1$
+ return s;
+ }
+
+ public String toStringHeader() {
+
+ String s = ""; //$NON-NLS-1$
+ if (modifiers != AccDefault) {
+ s += modifiersString(modifiers);
+ }
+ s += "aspect " + new String(name);//$NON-NLS-1$ //$NON-NLS-2$
+ if (superclass != null)
+ s += " extends " + superclass.toString(0); //$NON-NLS-1$
+ if (superInterfaces != null && superInterfaces.length > 0) {
+ s += (isInterface() ? " extends " : " implements ");//$NON-NLS-2$ //$NON-NLS-1$
+ for (int i = 0; i < superInterfaces.length; i++) {
+ s += superInterfaces[i].toString(0);
+ if (i != superInterfaces.length - 1)
+ s += ", "; //$NON-NLS-1$
+ };
+ };
+ return s;
+ }
+
+
+}
+
diff --git a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/AstUtil.java b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/AstUtil.java
new file mode 100644
index 000000000..9d17dddb7
--- /dev/null
+++ b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/AstUtil.java
@@ -0,0 +1,256 @@
+/* *******************************************************************
+ * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC).
+ * All rights reserved.
+ * This program and the accompanying materials are made available
+ * under the terms of the Common Public License v1.0
+ * which accompanies this distribution and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * Xerox/PARC initial implementation
+ * ******************************************************************/
+
+
+package org.aspectj.ajdt.internal.compiler.ast;
+
+import java.lang.reflect.Modifier;
+import java.util.*;
+import java.util.List;
+
+import org.aspectj.weaver.*;
+import org.aspectj.weaver.AjAttribute.AjSynthetic;
+import org.aspectj.weaver.ast.ASTNode;
+import org.aspectj.weaver.patterns.WildTypePattern;
+import org.eclipse.jdt.internal.compiler.ClassFile;
+import org.eclipse.jdt.internal.compiler.ast.*;
+import org.eclipse.jdt.internal.compiler.ast.ReturnStatement;
+import org.eclipse.jdt.internal.compiler.codegen.CodeStream;
+import org.eclipse.jdt.internal.compiler.env.IConstants;
+import org.eclipse.jdt.internal.compiler.impl.Constant;
+import org.eclipse.jdt.internal.compiler.lookup.*;
+import org.eclipse.jdt.internal.compiler.util.CharOperation;
+
+public class AstUtil {
+
+ private AstUtil() {}
+
+ public static void addMethodBinding(SourceTypeBinding sourceType, MethodBinding method) {
+ int len = sourceType.methods.length;
+ MethodBinding[] temp = new MethodBinding[len + 1];
+ System.arraycopy(sourceType.methods, 0, temp, 0, len);
+ temp[len] = method;
+ sourceType.methods = temp;
+ }
+
+
+ public static void addMethodDeclaration(TypeDeclaration typeDec, AbstractMethodDeclaration dec) {
+ AbstractMethodDeclaration[] methods = typeDec.methods;
+ int len = methods.length;
+ AbstractMethodDeclaration[] newMethods = new AbstractMethodDeclaration[len+1];
+ System.arraycopy(methods, 0, newMethods, 0, len);
+ newMethods[len] = dec;
+ typeDec.methods = newMethods;
+ }
+
+
+ public static Argument makeFinalArgument(char[] name, TypeBinding typeBinding) {
+ long pos = 0; //XXX encode start and end location
+ LocalVariableBinding binding =
+ new LocalVariableBinding(name, typeBinding, Modifier.FINAL, true);
+ Argument ret = new Argument(name, pos, makeTypeReference(typeBinding), Modifier.FINAL);
+ ret.binding = binding;
+ return ret;
+ }
+
+ public static TypeReference makeTypeReference(TypeBinding binding) {
+ // ??? does this work for primitives
+ QualifiedTypeReference ref =
+ new QualifiedTypeReference(new char[][] {binding.sourceName()}, binding, new long[] {0}); //???
+ ref.constant = Constant.NotAConstant;
+ return ref;
+ }
+
+
+ public static NameReference makeNameReference(TypeBinding binding) {
+ QualifiedNameReference ref =
+ new QualifiedNameReference(new char[][] {binding.sourceName()}, 0, 0);
+ ref.binding = binding; ref.constant = Constant.NotAConstant;
+ return ref;
+ }
+
+
+
+
+
+ public static ReturnStatement makeReturnStatement(Expression expr) {
+ return new ReturnStatement(expr, 0, 0);
+ }
+
+ public static MethodDeclaration makeMethodDeclaration(
+ MethodBinding binding)
+ {
+ MethodDeclaration ret = new MethodDeclaration(null);
+ ret.binding = binding;
+ int nargs = binding.parameters.length;
+ ret.arguments = new Argument[nargs];
+ for (int i=0; i < nargs; i++) {
+ ret.arguments[i] = makeFinalArgument(("arg"+i).toCharArray(),
+ binding.parameters[i]);
+ }
+ return ret;
+ }
+
+ public static void setStatements(
+ MethodDeclaration ret, List statements)
+ {
+ ret.statements =
+ (Statement[])statements.toArray(new Statement[statements.size()]);
+ }
+
+ public static SingleNameReference makeLocalVariableReference(
+ LocalVariableBinding binding)
+ {
+ SingleNameReference ret = new SingleNameReference(binding.name, 0);
+ ret.binding = binding;
+ ret.codegenBinding = binding;
+ ret.constant = AstNode.NotAConstant;
+ ret.bits &= ~AstNode.RestrictiveFlagMASK; // clear bits
+ ret.bits |= BindingIds.VARIABLE;
+ return ret;
+ }
+
+ public static SingleNameReference makeResolvedLocalVariableReference(
+ LocalVariableBinding binding)
+ {
+ SingleNameReference ret = new SingleNameReference(binding.name, 0);
+ ret.binding = binding;
+ ret.codegenBinding = binding;
+ ret.constant = AstNode.NotAConstant;
+ ret.bits &= ~AstNode.RestrictiveFlagMASK; // clear bits
+ ret.bits |= BindingIds.LOCAL;
+ return ret;
+ }
+
+ public static int makePublic(int modifiers) {
+ modifiers &= ~(IConstants.AccPublic | IConstants.AccPrivate | IConstants.AccProtected);
+ return modifiers | IConstants.AccPublic;
+ }
+
+ public static CompilationUnitScope getCompilationUnitScope(Scope scope) {
+ if (scope instanceof CompilationUnitScope) {
+ return (CompilationUnitScope)scope;
+ }
+ return getCompilationUnitScope(scope.parent);
+ }
+
+
+ public static void generateReturn(TypeBinding returnType, CodeStream codeStream) {
+ if (returnType.id == TypeIds.T_void) {
+ codeStream.return_();
+ } else if (returnType.isBaseType()) {
+ switch (returnType.id) {
+ case TypeBinding.T_boolean :
+ case TypeBinding.T_int :
+ case TypeBinding.T_byte :
+ case TypeBinding.T_short :
+ case TypeBinding.T_char :
+ codeStream.ireturn();
+ break;
+ case TypeBinding.T_float :
+ codeStream.freturn();
+ break;
+ case TypeBinding.T_long :
+ codeStream.lreturn();
+ break;
+ case TypeBinding.T_double :
+ codeStream.dreturn();
+ break;
+ default :
+ throw new RuntimeException("huh");
+ }
+ } else {
+ codeStream.areturn();
+ }
+ }
+
+ //XXX this could be inconsistent for wierd case, i.e. a class named "java_lang_String"
+ public static char[] makeMangledName(ReferenceBinding type) {
+ return CharOperation.concatWith(type.compoundName, '_');
+ }
+
+
+
+ public static final char[] PREFIX = "ajc".toCharArray();
+
+ //XXX not efficient
+ public static char[] makeAjcMangledName(char[] kind, ReferenceBinding type, char[] name) {
+ return CharOperation.concat(
+ CharOperation.concat(PREFIX, new char[] {'$'}, kind), '$', makeMangledName(type), '$', name);
+ }
+
+ public static char[] makeAjcMangledName(char[] kind, char[] p, char[] name) {
+ return CharOperation.concat(
+ CharOperation.concat(PREFIX, new char[] {'$'}, kind), '$', p, '$', name);
+ }
+
+ public static List getAjSyntheticAttribute() {
+ ArrayList ret = new ArrayList(1);
+ ret.add(new EclipseAttributeAdapter(new AjAttribute.AjSynthetic()));
+ return ret;
+ }
+
+ public static long makeLongPos(int start, int end) {
+ return (long)end | ((long)start << 32);
+ }
+ public static char[][] getCompoundName(String string) {
+ return WildTypePattern.splitNames(string);
+ }
+
+ public static TypeBinding[] insert(
+ TypeBinding first,
+ TypeBinding[] rest) {
+ if (rest == null) {
+ return new TypeBinding[] {first};
+ }
+
+ int len = rest.length;
+ TypeBinding[] ret = new TypeBinding[len+1];
+ ret[0] = first;
+ System.arraycopy(rest, 0, ret, 1, len);
+ return ret;
+ }
+ public static Argument[] insert(
+ Argument first,
+ Argument[] rest) {
+ if (rest == null) {
+ return new Argument[] {first};
+ }
+
+ int len = rest.length;
+ Argument[] ret = new Argument[len+1];
+ ret[0] = first;
+ System.arraycopy(rest, 0, ret, 1, len);
+ return ret;
+ }
+ public static Argument[] copyArguments(Argument[] inArgs) {
+ if (inArgs == null) return new Argument[] {};
+ int len = inArgs.length;
+ Argument[] outArgs = new Argument[len];
+ //??? we're not sure whether or not copying these is okay
+ System.arraycopy(inArgs, 0, outArgs, 0, len);
+ return outArgs;
+ }
+
+ public static Statement[] remove(int i, Statement[] statements) {
+ int len = statements.length;
+ Statement[] ret = new Statement[len-1];
+ System.arraycopy(statements, 0, ret, 0, i);
+ System.arraycopy(statements, i+1, ret, i, len-i-1);
+ return ret;
+ }
+ public static int slotsNeeded(TypeBinding type) {
+ if (type == BaseTypes.DoubleBinding || type == BaseTypes.LongBinding) return 2;
+ else return 1;
+ }
+
+}
diff --git a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/DeclareDeclaration.java b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/DeclareDeclaration.java
new file mode 100644
index 000000000..3433a0db1
--- /dev/null
+++ b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/DeclareDeclaration.java
@@ -0,0 +1,114 @@
+/* *******************************************************************
+ * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC).
+ * All rights reserved.
+ * This program and the accompanying materials are made available
+ * under the terms of the Common Public License v1.0
+ * which accompanies this distribution and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * Xerox/PARC initial implementation
+ * ******************************************************************/
+
+
+package org.aspectj.ajdt.internal.compiler.ast;
+
+import org.aspectj.ajdt.internal.compiler.lookup.*;
+import org.aspectj.ajdt.internal.compiler.lookup.EclipseScope;
+import org.aspectj.weaver.*;
+import org.aspectj.weaver.AjAttribute;
+import org.aspectj.weaver.patterns.*;
+import org.aspectj.weaver.patterns.Declare;
+import org.eclipse.jdt.internal.compiler.*;
+import org.eclipse.jdt.internal.compiler.CompilationResult;
+import org.eclipse.jdt.internal.compiler.ast.*;
+import org.eclipse.jdt.internal.compiler.lookup.*;
+import org.eclipse.jdt.internal.compiler.lookup.ClassScope;
+import org.eclipse.jdt.internal.compiler.parser.Parser;
+
+public class DeclareDeclaration extends MethodDeclaration implements IAjDeclaration {
+ public Declare declare;
+
+ /**
+ * Constructor for IntraTypeDeclaration.
+ */
+ static int counter = 0; //XXX evil
+ public DeclareDeclaration(CompilationResult result, Declare symbolicDeclare) {
+ super(result);
+ this.declare = symbolicDeclare;
+ if (declare != null) {
+ sourceStart = declare.getStart();
+ sourceEnd = declare.getEnd();
+ }
+ //??? we might need to set parameters to be empty
+ this.returnType = TypeReference.baseTypeReference(T_void, 0);
+ this.selector = ("ajc$declare_"+counter++).toCharArray(); //??? performance
+ }
+
+
+ /**
+ * A pointcut declaration exists in a classfile only as an attibute on the
+ * class. Unlike advice and inter-type declarations, it has no corresponding
+ * method.
+ */
+ public void generateCode(ClassScope classScope, ClassFile classFile) {
+ classFile.extraAttributes.add(new EclipseAttributeAdapter(new AjAttribute.DeclareAttribute(declare)));
+ return;
+ }
+
+ public void parseStatements(
+ Parser parser,
+ CompilationUnitDeclaration unit) {
+ // do nothing
+ }
+
+ public void resolveStatements(ClassScope upperScope) {
+ // do nothing
+ }
+
+// public boolean finishResolveTypes(SourceTypeBinding sourceTypeBinding) {
+// // there's nothing for our super to resolve usefully
+// //if (!super.finishResolveTypes(sourceTypeBinding)) return false;
+//// if (declare == null) return true;
+////
+//// EclipseScope scope = new EclipseScope(new FormalBinding[0], this.scope);
+////
+//// declare.resolve(scope);
+//// return true;
+// }
+
+
+ public void build(ClassScope classScope, CrosscuttingMembers xcut) {
+ if (declare == null) return;
+
+ EclipseScope scope = new EclipseScope(new FormalBinding[0], classScope);
+
+ declare.resolve(scope);
+ xcut.addDeclare(declare);
+
+ //EclipseWorld world = EclipseWorld.fromScopeLookupEnvironment(classScope);
+ //XXX need to work out the eclipse side of all this state
+//XXX world.addDeclare(world.resolve(EclipseWorld.fromBinding(classScope.referenceContext.binding)),
+//XXX declare, false);
+
+
+
+
+// binding = makeMethodBinding(classScope);
+// world.addTypeMunger(new EclipseNewMethodTypeMunger(binding));
+// //??? what do we need to know
+// munger = new NewMethodTypeMunger(
+// EclipseWorld.makeResolvedMember(binding.introducedMethod),
+// EclipseWorld.makeResolvedMember(super.binding), null);
+ }
+
+
+
+
+
+
+ public String toString(int tab) {
+ if (declare == null) return tabString(tab) + "<declare>";
+ else return tabString(tab) + declare.toString();
+ }
+}
diff --git a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/EclipseAttributeAdapter.java b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/EclipseAttributeAdapter.java
new file mode 100644
index 000000000..b7d534d14
--- /dev/null
+++ b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/EclipseAttributeAdapter.java
@@ -0,0 +1,34 @@
+/* *******************************************************************
+ * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC).
+ * All rights reserved.
+ * This program and the accompanying materials are made available
+ * under the terms of the Common Public License v1.0
+ * which accompanies this distribution and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * Xerox/PARC initial implementation
+ * ******************************************************************/
+
+
+package org.aspectj.ajdt.internal.compiler.ast;
+
+import org.aspectj.weaver.AjAttribute;
+import org.eclipse.jdt.internal.compiler.IAttribute;
+
+public class EclipseAttributeAdapter implements IAttribute {
+ AjAttribute attr;
+
+ public EclipseAttributeAdapter(AjAttribute attr) {
+ this.attr = attr;
+ }
+
+ public char[] getNameChars() {
+ return attr.getNameChars();
+ }
+
+ public byte[] getAllBytes(short nameIndex) {
+ return attr.getAllBytes(nameIndex);
+ }
+
+}
diff --git a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/IAjDeclaration.java b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/IAjDeclaration.java
new file mode 100644
index 000000000..e4e2f52f1
--- /dev/null
+++ b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/IAjDeclaration.java
@@ -0,0 +1,22 @@
+/* *******************************************************************
+ * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC).
+ * All rights reserved.
+ * This program and the accompanying materials are made available
+ * under the terms of the Common Public License v1.0
+ * which accompanies this distribution and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * Xerox/PARC initial implementation
+ * ******************************************************************/
+
+
+package org.aspectj.ajdt.internal.compiler.ast;
+
+import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
+
+public interface IAjDeclaration {
+// public String toString(int tab);
+// void postParse(TypeDeclaration typeDec);
+
+}
diff --git a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/IfMethodDeclaration.java b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/IfMethodDeclaration.java
new file mode 100644
index 000000000..1bca70dfb
--- /dev/null
+++ b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/IfMethodDeclaration.java
@@ -0,0 +1,55 @@
+/* *******************************************************************
+ * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC).
+ * All rights reserved.
+ * This program and the accompanying materials are made available
+ * under the terms of the Common Public License v1.0
+ * which accompanies this distribution and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * Xerox/PARC initial implementation
+ * ******************************************************************/
+
+
+package org.aspectj.ajdt.internal.compiler.ast;
+
+import org.aspectj.ajdt.internal.compiler.lookup.EclipseWorld;
+import org.aspectj.weaver.*;
+import org.aspectj.weaver.patterns.IfPointcut;
+import org.eclipse.jdt.internal.compiler.CompilationResult;
+import org.eclipse.jdt.internal.compiler.ast.*;
+import org.eclipse.jdt.internal.compiler.lookup.*;
+import org.eclipse.jdt.internal.compiler.lookup.SourceTypeBinding;
+import org.eclipse.jdt.internal.compiler.parser.Parser;
+
+public class IfMethodDeclaration extends MethodDeclaration {
+ IfPointcut ifPointcut;
+
+ public IfMethodDeclaration(CompilationResult compilationResult, IfPointcut ifPointcut) {
+ super(compilationResult);
+ this.ifPointcut = ifPointcut;
+ }
+
+ public void parseStatements(
+ Parser parser,
+ CompilationUnitDeclaration unit) {
+ // do nothing, we're already fully parsed
+ }
+
+ public void resolveStatements(ClassScope upperScope) {
+ super.resolveStatements(upperScope);
+ if (binding != null) {
+ ThisJoinPointVisitor tjp = new ThisJoinPointVisitor(this);
+ ifPointcut.extraParameterFlags |= tjp.removeUnusedExtraArguments();
+
+ //XXX this is where we should remove unavailable args if we're in a cflow
+
+ ifPointcut.testMethod = new ResolvedMember(
+ Member.METHOD,
+ EclipseWorld.fromBinding(binding.declaringClass),
+ this.modifiers, ResolvedTypeX.BOOLEAN,
+ new String(this.selector),
+ EclipseWorld.fromBindings(this.binding.parameters));
+ }
+ }
+}
diff --git a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/IfPseudoToken.java b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/IfPseudoToken.java
new file mode 100644
index 000000000..653039b96
--- /dev/null
+++ b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/IfPseudoToken.java
@@ -0,0 +1,111 @@
+/* *******************************************************************
+ * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC).
+ * All rights reserved.
+ * This program and the accompanying materials are made available
+ * under the terms of the Common Public License v1.0
+ * which accompanies this distribution and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * Xerox/PARC initial implementation
+ * ******************************************************************/
+
+
+package org.aspectj.ajdt.internal.compiler.ast;
+
+import java.lang.reflect.Modifier;
+
+import org.aspectj.ajdt.internal.compiler.lookup.EclipseWorld;
+import org.aspectj.weaver.*;
+import org.aspectj.weaver.ResolvedMember;
+import org.aspectj.weaver.patterns.*;
+import org.eclipse.jdt.internal.compiler.CompilationResult;
+import org.eclipse.jdt.internal.compiler.ast.*;
+import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
+import org.eclipse.jdt.internal.compiler.parser.*;
+
+
+/**
+ * (formals*): ... if(expr) ...
+ *
+ * generates the following:
+ * public static final boolean ajc$if_N(formals*, [thisJoinPoints as needed]) {
+ * return expr;
+ * }
+ *
+ * Here's the complicated bit, it deals with cflow:
+ * (a): ... this(a) && cflow(if (a == foo)) is an error.
+ * The way we capture this is:
+ * We generate the ajc$if method with an (a) parameter, we let eclipse do the proper
+ * name binding. We then, as a post pass (that we need to do anyway) look for the
+ * used parameters. If a is used, we signal an error because a was not one of the
+ * cflow variables.
+ * XXX we'll do this part after we do cflow
+ *
+ * The IfPointcut pcd then generates itself always as a dynamic test, it has to
+ * get the right parameters through any named pointcut references...
+ */
+public class IfPseudoToken extends PseudoToken {
+ public Expression expr;
+ public MethodDeclaration testMethod;
+ private IfPointcut pointcut;
+
+ public IfPseudoToken(
+ Parser parser,
+ Expression expr) {
+ super(parser, "if", false);
+ this.expr = expr;
+ }
+
+ public Pointcut maybeGetParsedPointcut() {
+ pointcut = new IfPointcut(new ResolvedMember(Member.METHOD, TypeX.OBJECT, 0, "if_", "()V"), 0);
+ return pointcut;
+ }
+
+
+ /**
+ * enclosingDec is either AdviceDeclaration or PointcutDeclaration
+ */
+ public void postParse(TypeDeclaration typeDec, MethodDeclaration enclosingDec) {
+// typeDec.scope.problemReporter().signalError(sourceStart, sourceEnd,
+// "if pcd is not implemented in 1.1alpha1");
+ //XXX need to implement correctly
+ if (pointcut == null) return;
+ testMethod = makeMethod(enclosingDec.compilationResult, enclosingDec);
+ AstUtil.addMethodDeclaration(typeDec, testMethod);
+ }
+
+
+ //XXX static state bad
+ private static int counter = 0;
+
+ //XXX todo: make sure that errors in Arguments only get displayed once
+ private MethodDeclaration makeMethod(CompilationResult result, MethodDeclaration enclosingDec) {
+ MethodDeclaration ret = new IfMethodDeclaration(result, pointcut);
+ ret.modifiers = AccStatic | AccFinal | AccPublic;
+ ret.returnType = AstUtil.makeTypeReference(TypeBinding.BooleanBinding);
+ ret.selector = ("ajc$if_" + counter++).toCharArray();
+ ret.arguments = makeArguments(enclosingDec);
+ ret.statements = new Statement[] {
+ new ReturnStatement(expr, expr.sourceStart, expr.sourceEnd)
+ };
+ return ret;
+ }
+
+ private Argument[] makeArguments(MethodDeclaration enclosingDec) {
+ Argument[] baseArguments = enclosingDec.arguments;
+ int len = baseArguments.length;
+ Argument[] ret = new Argument[len];
+ for (int i=0; i < len; i ++) {
+ Argument a = baseArguments[i];
+ ret[i] = new Argument(a.name, AstUtil.makeLongPos(a.sourceStart, a.sourceEnd),
+ a.type, Modifier.FINAL);
+ }
+ if (!(enclosingDec instanceof AdviceDeclaration)) {
+ ret = AdviceDeclaration.addTjpArguments(ret);
+ }
+
+ return ret;
+ }
+
+}
diff --git a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/InterTypeConstructorDeclaration.java b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/InterTypeConstructorDeclaration.java
new file mode 100644
index 000000000..275a3bc04
--- /dev/null
+++ b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/InterTypeConstructorDeclaration.java
@@ -0,0 +1,256 @@
+/* *******************************************************************
+ * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC).
+ * All rights reserved.
+ * This program and the accompanying materials are made available
+ * under the terms of the Common Public License v1.0
+ * which accompanies this distribution and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * Xerox/PARC initial implementation
+ * ******************************************************************/
+
+
+package org.aspectj.ajdt.internal.compiler.ast;
+
+import org.aspectj.ajdt.internal.compiler.lookup.*;
+import org.aspectj.weaver.*;
+import org.eclipse.jdt.internal.compiler.*;
+import org.eclipse.jdt.internal.compiler.ast.*;
+import org.eclipse.jdt.internal.compiler.lookup.*;
+import org.eclipse.jdt.internal.compiler.parser.Parser;
+
+
+public class InterTypeConstructorDeclaration extends InterTypeDeclaration {
+ private MethodDeclaration preMethod;
+ private ExplicitConstructorCall explicitConstructorCall = null;
+
+ public InterTypeConstructorDeclaration(CompilationResult result, TypeReference onType) {
+ super(result, onType);
+ }
+
+ public void parseStatements(Parser parser, CompilationUnitDeclaration unit) {
+ if (ignoreFurtherInvestigation)
+ return;
+ parser.parseAsConstructor(this, unit);
+ }
+
+ public void resolve(ClassScope upperScope) {
+ if (munger == null || binding == null) ignoreFurtherInvestigation = true;
+ if (ignoreFurtherInvestigation) return;
+
+ explicitConstructorCall = null;
+ if (statements != null && statements.length > 0 &&
+ statements[0] instanceof ExplicitConstructorCall)
+ {
+ explicitConstructorCall = (ExplicitConstructorCall) statements[0];
+ statements = AstUtil.remove(0, statements);
+ }
+
+ preMethod = makePreMethod(upperScope, explicitConstructorCall);
+
+ binding.parameters = AstUtil.insert(onTypeBinding, binding.parameters);
+ this.arguments = AstUtil.insert(
+ AstUtil.makeFinalArgument("ajc$this_".toCharArray(), onTypeBinding),
+ this.arguments);
+
+ super.resolve(upperScope);
+ }
+
+ private MethodDeclaration makePreMethod(ClassScope scope,
+ ExplicitConstructorCall explicitConstructorCall)
+ {
+ EclipseWorld world = EclipseWorld.fromScopeLookupEnvironment(scope);
+
+ TypeX aspectTypeX = EclipseWorld.fromBinding(binding.declaringClass);
+ TypeX targetTypeX = EclipseWorld.fromBinding(onTypeBinding);
+
+ ArrayBinding objectArrayBinding = scope.createArray(scope.getJavaLangObject(), 1);
+
+
+ MethodDeclaration pre = new MethodDeclaration(compilationResult);
+ pre.modifiers = AccPublic | AccStatic;
+ pre.returnType = AstUtil.makeTypeReference(objectArrayBinding);
+ pre.selector = NameMangler.postIntroducedConstructor(aspectTypeX, targetTypeX).toCharArray();
+
+
+ pre.arguments = AstUtil.copyArguments(this.arguments);
+
+ //XXX should do exceptions
+
+ pre.scope = new MethodScope(scope, pre, true);
+ //??? do we need to do anything with scope???
+
+ pre.binding = world.makeMethodBinding(
+ AjcMemberMaker.preIntroducedConstructor(aspectTypeX, targetTypeX,
+ world.fromBindings(binding.parameters)));
+
+ pre.bindArguments();
+ pre.bindThrownExceptions();
+
+
+ if (explicitConstructorCall == null) {
+ pre.statements = new Statement[] {};
+ } else {
+ pre.statements = new Statement[] {
+ explicitConstructorCall
+ };
+ }
+
+ InterTypeScope newParent =
+ new InterTypeScope(scope, onTypeBinding);
+ pre.scope.parent = newParent;
+
+ pre.resolveStatements(newParent);
+
+
+
+ int nParams = pre.arguments.length;
+ MethodBinding explicitConstructor = null;
+ if (explicitConstructorCall != null) {
+ explicitConstructor = explicitConstructorCall.binding;
+ if (explicitConstructor.alwaysNeedsAccessMethod()) {
+ explicitConstructor = explicitConstructor.getAccessMethod();
+ }
+ }
+
+ int nExprs;
+ if (explicitConstructor == null) nExprs = 0;
+ else nExprs = explicitConstructor.parameters.length;
+
+
+ ArrayInitializer init = new ArrayInitializer();
+ init.expressions = new Expression[nExprs + nParams];
+ int index = 0;
+ for (int i=0; i < nExprs; i++) {
+ if (i >= explicitConstructorCall.arguments.length) {
+ init.expressions[index++] = new NullLiteral(0, 0);
+ continue;
+ }
+
+
+ Expression arg = explicitConstructorCall.arguments[i];
+ ResolvedMember conversionMethod =
+ AjcMemberMaker.toObjectConversionMethod(world.fromBinding(explicitConstructorCall.binding.parameters[i]));
+ if (conversionMethod != null) {
+ arg = new KnownMessageSend(world.makeMethodBindingForCall(conversionMethod),
+ new CastExpression(new NullLiteral(0, 0),
+ AstUtil.makeTypeReference(world.makeTypeBinding(AjcMemberMaker.CONVERSIONS_TYPE))),
+ new Expression[] {arg });
+ }
+ init.expressions[index++] = arg;
+ }
+
+ for (int i=0; i < nParams; i++) {
+ LocalVariableBinding binding = pre.arguments[i].binding;
+ Expression arg = AstUtil.makeResolvedLocalVariableReference(binding);
+ ResolvedMember conversionMethod =
+ AjcMemberMaker.toObjectConversionMethod(world.fromBinding(binding.type));
+ if (conversionMethod != null) {
+ arg = new KnownMessageSend(world.makeMethodBindingForCall(conversionMethod),
+ new CastExpression(new NullLiteral(0, 0),
+ AstUtil.makeTypeReference(world.makeTypeBinding(AjcMemberMaker.CONVERSIONS_TYPE))),
+ new Expression[] {arg });
+ }
+ init.expressions[index++] = arg;
+ }
+
+ init.binding =objectArrayBinding;
+
+ ArrayAllocationExpression newArray = new ArrayAllocationExpression();
+ newArray.initializer = init;
+ newArray.type = AstUtil.makeTypeReference(scope.getJavaLangObject());
+ newArray.dimensions = new Expression[1];
+ newArray.constant = NotAConstant;
+
+
+
+
+ pre.statements = new Statement[] {
+ new ReturnStatement(newArray, 0, 0),
+ };
+ return pre;
+ }
+
+
+
+
+ public void build(ClassScope classScope, CrosscuttingMembers xcut) {
+ EclipseWorld world = EclipseWorld.fromScopeLookupEnvironment(classScope);
+
+ binding = classScope.referenceContext.binding.resolveTypesFor(binding);
+
+ resolveOnType(classScope);
+ if (ignoreFurtherInvestigation) return;
+
+
+ if (onTypeBinding.isInterface()) {
+ ignoreFurtherInvestigation = true;
+ return;
+ }
+
+ if (onTypeBinding.isNestedType()) {
+ classScope.problemReporter().signalError(sourceStart, sourceEnd,
+ "can't define constructors on nested types (compiler limitation)");
+ ignoreFurtherInvestigation = true;
+ return;
+ }
+
+ ResolvedTypeX declaringTypeX = world.fromEclipse(onTypeBinding);
+ ResolvedTypeX aspectType = world.fromEclipse(classScope.referenceContext.binding);
+
+ ResolvedMember bindingAsMember = world.makeResolvedMember(binding);
+
+ ResolvedMember signature =
+ new ResolvedMember(Member.CONSTRUCTOR, declaringTypeX, declaredModifiers,
+ ResolvedTypeX.VOID, "<init>", bindingAsMember.getParameterTypes());
+
+ ResolvedMember syntheticInterMember =
+ AjcMemberMaker.interConstructor(declaringTypeX, signature, aspectType);
+
+ NewConstructorTypeMunger myMunger =
+ new NewConstructorTypeMunger(signature, syntheticInterMember, null, null);
+ this.munger = myMunger;
+
+ this.selector = binding.selector =
+ NameMangler.postIntroducedConstructor(
+ EclipseWorld.fromBinding(binding.declaringClass),
+ declaringTypeX).toCharArray();
+
+ xcut.addTypeMunger(new EclipseTypeMunger(myMunger, aspectType, this));
+ }
+
+
+ private AjAttribute makeAttribute(EclipseWorld world) {
+ if (explicitConstructorCall != null) {
+ MethodBinding explicitConstructor = explicitConstructorCall.binding;
+ if (explicitConstructor.alwaysNeedsAccessMethod()) {
+ explicitConstructor = explicitConstructor.getAccessMethod();
+ }
+
+
+ ((NewConstructorTypeMunger)munger).setExplicitConstructor(
+ world.makeResolvedMember(explicitConstructor));
+ } else {
+ ((NewConstructorTypeMunger)munger).setExplicitConstructor(
+ new ResolvedMember(Member.CONSTRUCTOR,
+ EclipseWorld.fromBinding(onTypeBinding.superclass()),
+ 0, ResolvedTypeX.VOID, "<init>", TypeX.NONE));
+ }
+ return new AjAttribute.TypeMunger(munger);
+ }
+
+
+ public void generateCode(ClassScope classScope, ClassFile classFile) {
+ if (ignoreFurtherInvestigation) return;
+ EclipseWorld world = EclipseWorld.fromScopeLookupEnvironment(classScope);
+ classFile.extraAttributes.add(new EclipseAttributeAdapter(makeAttribute(world)));
+ super.generateCode(classScope, classFile);
+
+ preMethod.generateCode(classScope, classFile);
+ }
+ protected Shadow.Kind getShadowKindForBody() {
+ return Shadow.ConstructorExecution;
+ }
+
+}
diff --git a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/InterTypeDeclaration.java b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/InterTypeDeclaration.java
new file mode 100644
index 000000000..62c840f58
--- /dev/null
+++ b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/InterTypeDeclaration.java
@@ -0,0 +1,131 @@
+/* *******************************************************************
+ * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC).
+ * All rights reserved.
+ * This program and the accompanying materials are made available
+ * under the terms of the Common Public License v1.0
+ * which accompanies this distribution and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * Xerox/PARC initial implementation
+ * ******************************************************************/
+
+
+package org.aspectj.ajdt.internal.compiler.ast;
+
+import java.lang.reflect.Modifier;
+import java.util.*;
+
+import org.aspectj.ajdt.internal.compiler.lookup.*;
+import org.aspectj.weaver.*;
+import org.eclipse.jdt.internal.compiler.*;
+import org.eclipse.jdt.internal.compiler.CompilationResult;
+import org.eclipse.jdt.internal.compiler.ast.*;
+import org.eclipse.jdt.internal.compiler.lookup.*;
+import org.eclipse.jdt.internal.compiler.util.CharOperation;
+
+public abstract class InterTypeDeclaration extends MethodDeclaration implements IAjDeclaration {
+ //public AstNode myDeclaration;
+ public TypeReference onType;
+ protected ReferenceBinding onTypeBinding;
+
+ protected ResolvedTypeMunger munger;
+ protected int declaredModifiers;
+ protected char[] declaredSelector;
+
+ //protected Set superMethodsCalled;
+
+ public InterTypeDeclaration(CompilationResult result, TypeReference onType) {
+ super(result);
+ this.onType = onType;
+ modifiers = AccPublic | AccStatic;
+ }
+
+ public void setDeclaredModifiers(int modifiers) {
+ this.declaredModifiers = modifiers;
+ }
+
+ public void setSelector(char[] selector) {
+ declaredSelector = selector;
+ this.selector = CharOperation.concat(selector, Integer.toHexString(sourceStart).toCharArray());
+ }
+
+ public void resolve(ClassScope upperScope) {
+ if (ignoreFurtherInvestigation) return;
+
+
+ ClassScope newParent = new InterTypeScope(upperScope, onTypeBinding);
+ //interBinding.introducedField.declaringClass);
+ scope.parent = newParent;
+ this.scope.isStatic = Modifier.isStatic(declaredModifiers);
+ super.resolve(newParent);
+ fixSuperCallsInBody();
+ }
+
+ /**
+ * Called from AspectDeclarations.buildInterTypeAndPerClause
+ */
+ public abstract void build(ClassScope classScope, CrosscuttingMembers xcut);
+
+ public void fixSuperCallsInBody() {
+ SuperFixerVisitor v = new SuperFixerVisitor(this, onTypeBinding);
+ this.traverse(v, (ClassScope)null);
+ HashSet set = new HashSet();
+ for (Iterator i = v.superMethodsCalled.iterator(); i.hasNext(); ) {
+ MethodBinding b = (MethodBinding)i.next();
+ set.add(EclipseWorld.makeResolvedMember(b));
+ }
+
+ munger.setSuperMethodsCalled(set);
+ }
+
+ protected void resolveOnType(ClassScope classScope) {
+ checkSpec();
+ onTypeBinding = (ReferenceBinding)onType.getTypeBinding(classScope);
+ if (!onTypeBinding.isValidBinding()) {
+ if (onTypeBinding instanceof ProblemReferenceBinding) {
+ classScope.problemReporter().invalidType(onType, onTypeBinding);
+ } else {
+ //XXX trouble
+ }
+ ignoreFurtherInvestigation = true;
+ }
+ }
+
+
+ protected void checkSpec() {
+ if (Modifier.isProtected(declaredModifiers)) {
+ scope.problemReporter().signalError(sourceStart, sourceEnd,
+ "protected inter-type declarations are not allowed");
+ ignoreFurtherInvestigation = true;
+ }
+ }
+
+ protected List makeEffectiveSignatureAttribute(
+ ResolvedMember sig,
+ Shadow.Kind kind,
+ boolean weaveBody)
+ {
+ List l = new ArrayList(1);
+ l.add(new EclipseAttributeAdapter(
+ new AjAttribute.EffectiveSignatureAttribute(sig, kind, weaveBody)));
+ return l;
+ }
+
+ protected int generateInfoAttributes(ClassFile classFile) {
+ munger.getSignature().setPosition(sourceStart, sourceEnd);
+
+ //System.out.println("generating effective for " + this);
+ List l;;
+ Shadow.Kind kind = getShadowKindForBody();
+ if (kind != null) {
+ l = makeEffectiveSignatureAttribute(munger.getSignature(), kind, true);
+ } else {
+ l = new ArrayList(0); //AstUtil.getAjSyntheticAttribute();
+ }
+
+ return classFile.generateMethodInfoAttribute(binding, l);
+ }
+
+ protected abstract Shadow.Kind getShadowKindForBody();
+}
diff --git a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/InterTypeFieldDeclaration.java b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/InterTypeFieldDeclaration.java
new file mode 100644
index 000000000..0ed6b63c9
--- /dev/null
+++ b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/InterTypeFieldDeclaration.java
@@ -0,0 +1,286 @@
+/* *******************************************************************
+ * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC).
+ * All rights reserved.
+ * This program and the accompanying materials are made available
+ * under the terms of the Common Public License v1.0
+ * which accompanies this distribution and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * Xerox/PARC initial implementation
+ * ******************************************************************/
+
+
+package org.aspectj.ajdt.internal.compiler.ast;
+
+import java.lang.reflect.Modifier;
+
+import org.aspectj.ajdt.internal.compiler.lookup.*;
+import org.aspectj.weaver.*;
+import org.eclipse.jdt.internal.compiler.*;
+import org.eclipse.jdt.internal.compiler.ast.*;
+import org.eclipse.jdt.internal.compiler.codegen.CodeStream;
+import org.eclipse.jdt.internal.compiler.impl.Constant;
+import org.eclipse.jdt.internal.compiler.lookup.*;
+import org.eclipse.jdt.internal.compiler.parser.Parser;
+
+/**
+ * returnType encodes the type of the field
+ * selector encodes the name
+ */
+public class InterTypeFieldDeclaration extends InterTypeDeclaration {
+ public Expression initialization;
+ //public InterTypeFieldBinding interBinding;
+
+ public InterTypeFieldDeclaration(CompilationResult result, TypeReference onType) {
+ super(result, onType);
+ }
+
+
+ public void parseStatements(Parser parser, CompilationUnitDeclaration unit) {
+ //we don't have a body to parse
+ }
+
+
+ public void resolveOnType(ClassScope classScope) {
+ super.resolveOnType(classScope);
+ if (ignoreFurtherInvestigation) return;
+ if (Modifier.isStatic(declaredModifiers) && onTypeBinding.isInterface()) {
+ scope.problemReporter().signalError(sourceStart, sourceEnd,
+ "static inter-type field on interface not supported");
+ ignoreFurtherInvestigation = true;
+ }
+ }
+
+
+ public void resolve(ClassScope upperScope) {
+ if (munger == null) ignoreFurtherInvestigation = true;
+ if (ignoreFurtherInvestigation) return;
+
+ EclipseWorld world = EclipseWorld.fromScopeLookupEnvironment(upperScope);
+ ResolvedMember sig = munger.getSignature();
+ TypeX aspectType = EclipseWorld.fromBinding(upperScope.referenceContext.binding);
+
+ if (initialization == null) {
+ this.statements = new Statement[] {
+ new ReturnStatement(null, 0, 0),
+ };
+ } else if (!onTypeBinding.isInterface()) {
+
+ FieldBinding interField = world.makeFieldBinding(
+ AjcMemberMaker.interFieldClassField(sig, aspectType));
+ Reference ref = new KnownFieldReference(interField, 0);
+ this.statements = new Statement[] {
+ new Assignment(ref, initialization, initialization.sourceEnd),
+ };
+ } else {
+ //XXX something is broken about this logic. Can we write to static interface fields?
+ MethodBinding writeMethod = world.makeMethodBinding(
+ AjcMemberMaker.interFieldInterfaceSetter(sig, sig.getDeclaringType().resolve(world), aspectType));
+ if (Modifier.isStatic(declaredModifiers)) {
+ this.statements = new Statement[] {
+ new KnownMessageSend(writeMethod,
+ AstUtil.makeNameReference(writeMethod.declaringClass),
+ new Expression[] {initialization}),
+ };
+ } else {
+ this.statements = new Statement[] {
+ new KnownMessageSend(writeMethod,
+ AstUtil.makeLocalVariableReference(arguments[0].binding),
+ new Expression[] {initialization}),
+ };
+ }
+ }
+
+ super.resolve(upperScope);
+ }
+
+
+ public void setInitialization(Expression initialization) {
+ this.initialization = initialization;
+
+ }
+
+ public void build(ClassScope classScope, CrosscuttingMembers xcut) {
+ EclipseWorld world = EclipseWorld.fromScopeLookupEnvironment(classScope);
+ resolveOnType(classScope);
+
+ binding = classScope.referenceContext.binding.resolveTypesFor(binding);
+ if (ignoreFurtherInvestigation) return;
+
+ if (!Modifier.isStatic(declaredModifiers)) {
+ super.binding.parameters = new TypeBinding[] {
+ onTypeBinding,
+ };
+ this.arguments = new Argument[] {
+ AstUtil.makeFinalArgument("ajc$this_".toCharArray(), onTypeBinding),
+ };
+ }
+
+ ResolvedMember sig =
+ new ResolvedMember(Member.FIELD, EclipseWorld.fromBinding(onTypeBinding),
+ declaredModifiers, EclipseWorld.fromBinding(binding.returnType),
+ new String(declaredSelector), TypeX.NONE);
+
+ NewFieldTypeMunger myMunger = new NewFieldTypeMunger(sig, null);
+ this.munger = myMunger;
+ ResolvedTypeX aspectType = world.fromEclipse(classScope.referenceContext.binding);
+ ResolvedMember me =
+ myMunger.getInitMethod(aspectType);
+ this.selector = binding.selector = me.getName().toCharArray();
+ this.binding.returnType = TypeBinding.VoidBinding;
+ //??? all other pieces should already match
+
+ xcut.addTypeMunger(new EclipseTypeMunger(myMunger, aspectType, this));
+
+// interBinding = new InterTypeFieldBinding(name, type, declaredModifiers,
+// declaringClass, constant, withinType);
+
+// //XXX handle problem bindings
+// TypeBinding type = returnType.getTypeBinding(classScope);
+// char[] name = selector;
+// super.binding.returnType = type;
+//
+// if (ignoreFurtherInvestigation) return;
+//
+//
+// ReferenceBinding withinType = classScope.referenceContext.binding;
+//
+// this.returnType.binding = super.binding.returnType = TypeBinding.VoidBinding;
+// //this.modifiers = super.binding.modifiers = AccStatic | AccPublic;
+//
+// TypeX aspectTypeX = EclipseWorld.fromBinding(withinType);
+// TypeX onTypeX = EclipseWorld.fromBinding(declaringClass);
+//
+// this.selector =
+// NameMangler.interFieldInitializer(aspectTypeX, onTypeX, new String(selector)).toCharArray();
+//
+// super.binding.selector = this.selector;
+// Constant constant = Constant.NotAConstant;
+// //XXX this is not completely correct, it will miss all constants
+//// if (initialization instanceof Literal) {
+//// ((Literal)initialization).computeConstant();
+//// constant = initialization.constant;
+//// }
+
+
+
+
+
+
+ }
+
+
+ private AjAttribute makeAttribute() {
+ return new AjAttribute.TypeMunger(munger);
+ }
+
+ public void generateCode(ClassScope classScope, ClassFile classFile) {
+ if (ignoreFurtherInvestigation) return;
+
+ classFile.extraAttributes.add(new EclipseAttributeAdapter(makeAttribute()));
+ super.generateCode(classScope, classFile);
+ generateDispatchMethods(classScope, classFile);
+// interBinding.reader.generateMethod(this, classScope, classFile);
+// interBinding.writer.generateMethod(this, classScope, classFile);
+ }
+
+ private void generateDispatchMethods(ClassScope classScope, ClassFile classFile) {
+ EclipseWorld world = EclipseWorld.fromScopeLookupEnvironment(classScope);
+ ResolvedMember sig = munger.getSignature();
+ TypeX aspectType = EclipseWorld.fromBinding(classScope.referenceContext.binding);
+ generateDispatchMethod(world, sig, aspectType, classScope, classFile, true);
+ generateDispatchMethod(world, sig, aspectType, classScope, classFile, false);
+ }
+
+ private void generateDispatchMethod(
+ EclipseWorld world,
+ ResolvedMember sig,
+ TypeX aspectType,
+ ClassScope classScope,
+ ClassFile classFile,
+ boolean isGetter)
+ {
+ MethodBinding binding;
+ if (isGetter) {
+ binding = world.makeMethodBinding(AjcMemberMaker.interFieldGetDispatcher(sig, aspectType));
+ } else {
+ binding = world.makeMethodBinding(AjcMemberMaker.interFieldSetDispatcher(sig, aspectType));
+ }
+ classFile.generateMethodInfoHeader(binding);
+ int methodAttributeOffset = classFile.contentsOffset;
+ int attributeNumber = classFile.generateMethodInfoAttribute(binding,
+ makeEffectiveSignatureAttribute(sig, isGetter ? Shadow.FieldGet : Shadow.FieldSet, false));
+ int codeAttributeOffset = classFile.contentsOffset;
+ classFile.generateCodeAttributeHeader();
+ CodeStream codeStream = classFile.codeStream;
+ codeStream.reset(this, classFile);
+
+ FieldBinding classField = world.makeFieldBinding(
+ AjcMemberMaker.interFieldClassField(sig, aspectType));
+
+ codeStream.initializeMaxLocals(binding);
+ if (isGetter) {
+ if (onTypeBinding.isInterface()) {
+ MethodBinding readMethod = world.makeMethodBinding(
+ AjcMemberMaker.interFieldInterfaceGetter(
+ sig, world.resolve(sig.getDeclaringType()), aspectType));
+ generateInterfaceReadBody(binding, readMethod, codeStream);
+ } else {
+ generateClassReadBody(binding, classField, codeStream);
+ }
+ } else {
+ if (onTypeBinding.isInterface()) {
+ MethodBinding writeMethod = world.makeMethodBinding(
+ AjcMemberMaker.interFieldInterfaceSetter(
+ sig, world.resolve(sig.getDeclaringType()), aspectType));
+ generateInterfaceWriteBody(binding, writeMethod, codeStream);
+ } else {
+ generateClassWriteBody(binding, classField, codeStream);
+ }
+ }
+ AstUtil.generateReturn(binding.returnType, codeStream);
+
+ classFile.completeCodeAttribute(codeAttributeOffset);
+ attributeNumber++;
+ classFile.completeMethodInfo(methodAttributeOffset, attributeNumber);
+ }
+
+ private void generateInterfaceReadBody(MethodBinding binding, MethodBinding readMethod, CodeStream codeStream) {
+ codeStream.aload_0();
+ codeStream.invokeinterface(readMethod);
+ }
+
+
+ private void generateInterfaceWriteBody(MethodBinding binding, MethodBinding writeMethod, CodeStream codeStream) {
+ codeStream.aload_0();
+ codeStream.load(writeMethod.parameters[0], 1);
+ codeStream.invokeinterface(writeMethod);
+ }
+
+
+
+ private void generateClassReadBody(MethodBinding binding, FieldBinding field, CodeStream codeStream) {
+ if (field.isStatic()) {
+ codeStream.getstatic(field);
+ } else {
+ codeStream.aload_0();
+ codeStream.getfield(field);
+ }
+ }
+
+ private void generateClassWriteBody(MethodBinding binding, FieldBinding field, CodeStream codeStream) {
+ if (field.isStatic()) {
+ codeStream.load(field.type, 0);
+ codeStream.putstatic(field);
+ } else {
+ codeStream.aload_0();
+ codeStream.load(field.type, 1);
+ codeStream.putfield(field);
+ }
+ }
+
+ protected Shadow.Kind getShadowKindForBody() {
+ return null;
+ }
+}
diff --git a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/InterTypeMethodDeclaration.java b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/InterTypeMethodDeclaration.java
new file mode 100644
index 000000000..8190809ea
--- /dev/null
+++ b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/InterTypeMethodDeclaration.java
@@ -0,0 +1,175 @@
+/* *******************************************************************
+ * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC).
+ * All rights reserved.
+ * This program and the accompanying materials are made available
+ * under the terms of the Common Public License v1.0
+ * which accompanies this distribution and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * Xerox/PARC initial implementation
+ * ******************************************************************/
+
+
+package org.aspectj.ajdt.internal.compiler.ast;
+
+import java.lang.reflect.Modifier;
+
+import org.aspectj.ajdt.internal.compiler.lookup.*;
+import org.aspectj.weaver.*;
+import org.aspectj.weaver.Shadow.Kind;
+import org.eclipse.jdt.internal.compiler.*;
+import org.eclipse.jdt.internal.compiler.ast.*;
+import org.eclipse.jdt.internal.compiler.codegen.CodeStream;
+import org.eclipse.jdt.internal.compiler.flow.*;
+import org.eclipse.jdt.internal.compiler.lookup.*;
+import org.eclipse.jdt.internal.compiler.parser.Parser;
+
+
+public class InterTypeMethodDeclaration extends InterTypeDeclaration {
+ public InterTypeMethodDeclaration(CompilationResult result, TypeReference onType) {
+ super(result, onType);
+ }
+
+ public void parseStatements(Parser parser, CompilationUnitDeclaration unit) {
+ if (ignoreFurtherInvestigation)
+ return;
+ if (!Modifier.isAbstract(declaredModifiers)) {
+ parser.parse(this, unit);
+ }
+ }
+
+
+ public void analyseCode(
+ ClassScope currentScope,
+ FlowContext flowContext,
+ FlowInfo flowInfo)
+ {
+ if (Modifier.isAbstract(declaredModifiers)) return;
+
+ super.analyseCode(currentScope, flowContext, flowInfo);
+ }
+
+ public void resolve(ClassScope upperScope) {
+ if (munger == null) ignoreFurtherInvestigation = true;
+ if (ignoreFurtherInvestigation) return;
+
+ if (!Modifier.isStatic(declaredModifiers)) {
+ this.arguments = AstUtil.insert(
+ AstUtil.makeFinalArgument("ajc$this_".toCharArray(), onTypeBinding),
+ this.arguments);
+ binding.parameters = AstUtil.insert(onTypeBinding, binding.parameters);
+ }
+
+ super.resolve(upperScope);
+ }
+ public void resolveStatements(ClassScope upperScope) {
+ if (!Modifier.isAbstract(declaredModifiers)) super.resolveStatements(upperScope);
+ }
+
+
+
+ public void build(ClassScope classScope, CrosscuttingMembers xcut) {
+ EclipseWorld world = EclipseWorld.fromScopeLookupEnvironment(classScope);
+
+ resolveOnType(classScope);
+ if (ignoreFurtherInvestigation) return;
+
+ binding = classScope.referenceContext.binding.resolveTypesFor(binding);
+ ResolvedMember sig = new ResolvedMember(Member.METHOD, EclipseWorld.fromBinding(onTypeBinding),
+ declaredModifiers, EclipseWorld.fromBinding(binding.returnType), new String(declaredSelector),
+ EclipseWorld.fromBindings(binding.parameters));
+
+ NewMethodTypeMunger myMunger = new NewMethodTypeMunger(sig, null);
+ this.munger = myMunger;
+ ResolvedTypeX aspectType = world.fromEclipse(classScope.referenceContext.binding);
+ ResolvedMember me =
+ myMunger.getDispatchMethod(aspectType);
+ this.selector = binding.selector = me.getName().toCharArray();
+
+ xcut.addTypeMunger(new EclipseTypeMunger(myMunger, aspectType, this));
+ }
+
+
+ private AjAttribute makeAttribute() {
+ return new AjAttribute.TypeMunger(munger);
+ }
+
+
+ public void generateCode(ClassScope classScope, ClassFile classFile) {
+ if (ignoreFurtherInvestigation) {
+ System.err.println("no code for " + this);
+ return;
+ }
+
+ classFile.extraAttributes.add(new EclipseAttributeAdapter(makeAttribute()));
+
+ if (!Modifier.isAbstract(declaredModifiers)) {
+ super.generateCode(classScope, classFile);
+ }
+
+ generateDispatchMethod(classScope, classFile);
+ }
+
+ public void generateDispatchMethod(ClassScope classScope, ClassFile classFile) {
+ EclipseWorld world = EclipseWorld.fromScopeLookupEnvironment(classScope);
+
+ TypeX aspectType = EclipseWorld.fromBinding(classScope.referenceContext.binding);
+ ResolvedMember signature = munger.getSignature();
+
+ ResolvedMember dispatchMember =
+ AjcMemberMaker.interMethodDispatcher(signature, aspectType);
+ MethodBinding dispatchBinding = world.makeMethodBinding(dispatchMember);
+ MethodBinding introducedMethod =
+ world.makeMethodBinding(AjcMemberMaker.interMethod(signature, aspectType, onTypeBinding.isInterface()));
+
+ classFile.generateMethodInfoHeader(dispatchBinding);
+ int methodAttributeOffset = classFile.contentsOffset;
+ int attributeNumber = classFile.generateMethodInfoAttribute(dispatchBinding,
+ makeEffectiveSignatureAttribute(signature, Shadow.MethodCall, false));
+ int codeAttributeOffset = classFile.contentsOffset;
+ classFile.generateCodeAttributeHeader();
+ CodeStream codeStream = classFile.codeStream;
+ codeStream.reset(this, classFile);
+
+ codeStream.initializeMaxLocals(dispatchBinding);
+
+ MethodBinding methodBinding = introducedMethod;
+ TypeBinding[] parameters = methodBinding.parameters;
+ int length = parameters.length;
+ int resolvedPosition;
+ if (methodBinding.isStatic())
+ resolvedPosition = 0;
+ else {
+ codeStream.aload_0();
+ resolvedPosition = 1;
+ }
+ for (int i = 0; i < length; i++) {
+ codeStream.load(parameters[i], resolvedPosition);
+ if ((parameters[i] == DoubleBinding) || (parameters[i] == LongBinding))
+ resolvedPosition += 2;
+ else
+ resolvedPosition++;
+ }
+ TypeBinding type;
+ if (methodBinding.isStatic())
+ codeStream.invokestatic(methodBinding);
+ else {
+ if (methodBinding.declaringClass.isInterface()){
+ codeStream.invokeinterface(methodBinding);
+ } else {
+ codeStream.invokevirtual(methodBinding);
+ }
+ }
+ AstUtil.generateReturn(dispatchBinding.returnType, codeStream);
+
+ classFile.completeCodeAttribute(codeAttributeOffset);
+ attributeNumber++;
+ classFile.completeMethodInfo(methodAttributeOffset, attributeNumber);
+ }
+
+
+ protected Shadow.Kind getShadowKindForBody() {
+ return Shadow.MethodExecution;
+ }
+}
diff --git a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/KnownFieldReference.java b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/KnownFieldReference.java
new file mode 100644
index 000000000..d2caddc25
--- /dev/null
+++ b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/KnownFieldReference.java
@@ -0,0 +1,39 @@
+/* *******************************************************************
+ * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC).
+ * All rights reserved.
+ * This program and the accompanying materials are made available
+ * under the terms of the Common Public License v1.0
+ * which accompanies this distribution and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * Xerox/PARC initial implementation
+ * ******************************************************************/
+
+
+package org.aspectj.ajdt.internal.compiler.ast;
+
+import org.eclipse.jdt.internal.compiler.ast.*;
+import org.eclipse.jdt.internal.compiler.ast.FieldReference;
+import org.eclipse.jdt.internal.compiler.impl.Constant;
+import org.eclipse.jdt.internal.compiler.lookup.*;
+
+public class KnownFieldReference extends QualifiedNameReference {
+
+ //XXX handle source locations
+ public KnownFieldReference(FieldBinding binding, long pos) {
+ super(new char[][] {binding.name}, 0, 0);
+ this.binding = this.codegenBinding = binding;
+ this.constant = Constant.NotAConstant;
+ this.receiverType = this.actualReceiverType =
+ binding.declaringClass;
+
+ this.bits = FIELD;
+ //this.receiver = AstUtil.makeTypeReference(binding.declaringClass);
+ }
+
+ public TypeBinding resolveType(BlockScope scope) {
+ return fieldBinding().type;
+ }
+
+}
diff --git a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/KnownMessageSend.java b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/KnownMessageSend.java
new file mode 100644
index 000000000..45eaa8c38
--- /dev/null
+++ b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/KnownMessageSend.java
@@ -0,0 +1,57 @@
+/* *******************************************************************
+ * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC).
+ * All rights reserved.
+ * This program and the accompanying materials are made available
+ * under the terms of the Common Public License v1.0
+ * which accompanies this distribution and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * Xerox/PARC initial implementation
+ * ******************************************************************/
+
+
+package org.aspectj.ajdt.internal.compiler.ast;
+
+import java.util.Arrays;
+
+import org.eclipse.jdt.internal.compiler.ast.*;
+import org.eclipse.jdt.internal.compiler.ast.MessageSend;
+import org.eclipse.jdt.internal.compiler.codegen.CodeStream;
+import org.eclipse.jdt.internal.compiler.lookup.*;
+import org.eclipse.jdt.internal.compiler.lookup.MethodBinding;
+
+public class KnownMessageSend extends MessageSend {
+
+ public KnownMessageSend(MethodBinding binding, Expression receiver, Expression[] arguments) {
+ super();
+ this.binding = this.codegenBinding = binding;
+ this.arguments = arguments;
+ this.receiver = receiver;
+ this.selector = binding.selector;
+ constant = NotAConstant;
+ }
+
+ public void manageSyntheticAccessIfNecessary(BlockScope currentScope) {
+ return;
+ }
+
+ protected void resolveMethodBinding(
+ BlockScope scope,
+ TypeBinding[] argumentTypes) {
+ // we've already resolved this
+ }
+
+ public String toStringExpression() {
+ return "KnownMessageSend";
+ }
+
+ public void generateCode(
+ BlockScope currentScope,
+ CodeStream codeStream,
+ boolean valueRequired) {
+ //System.out.println("about to generate: " +this + " args: " + Arrays.asList(arguments));
+ super.generateCode(currentScope, codeStream, valueRequired);
+ }
+
+}
diff --git a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/PointcutDeclaration.java b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/PointcutDeclaration.java
new file mode 100644
index 000000000..294258eca
--- /dev/null
+++ b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/PointcutDeclaration.java
@@ -0,0 +1,171 @@
+/* *******************************************************************
+ * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC).
+ * All rights reserved.
+ * This program and the accompanying materials are made available
+ * under the terms of the Common Public License v1.0
+ * which accompanies this distribution and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * Xerox/PARC initial implementation
+ * ******************************************************************/
+
+
+package org.aspectj.ajdt.internal.compiler.ast;
+
+import java.io.*;
+import java.io.IOException;
+
+import org.aspectj.ajdt.internal.compiler.lookup.EclipseWorld;
+import org.aspectj.weaver.*;
+import org.aspectj.weaver.ResolvedPointcutDefinition;
+import org.aspectj.weaver.patterns.Pointcut;
+import org.eclipse.jdt.internal.compiler.*;
+import org.eclipse.jdt.internal.compiler.ast.*;
+import org.eclipse.jdt.internal.compiler.lookup.*;
+import org.eclipse.jdt.internal.compiler.lookup.ClassScope;
+import org.eclipse.jdt.internal.compiler.parser.Parser;
+
+
+public class PointcutDeclaration extends MethodDeclaration implements IAjDeclaration {
+ public PointcutDesignator pointcutDesignator;
+
+ public PointcutDeclaration(CompilationResult compilationResult) {
+ super(compilationResult);
+ this.returnType = TypeReference.baseTypeReference(T_void, 0);
+ }
+
+// public PointcutDeclaration(MethodDeclaration decl, Parser parser) {
+// this(decl.compilationResult);
+// this.sourceEnd = decl.sourceEnd;
+// this.sourceStart = decl.sourceStart;
+//
+// this.arguments = decl.arguments;
+// if (this.arguments == null) this.arguments = new Argument[0];
+// this.modifiers = decl.modifiers;
+//// if ((modifiers & AccAbstract) == 0) {
+//// modifiers |= AccNative;
+//// }
+//// modifiers |= AccSemicolonBody; //XXX hack to make me have no body
+//
+// this.modifiersSourceStart = decl.modifiersSourceStart;
+// this.selector = decl.selector;
+// if (decl.thrownExceptions != null && decl.thrownExceptions.length > 0) {
+// //XXX need a better problem to report
+// TypeReference e1 = decl.thrownExceptions[0];
+// parser.problemReporter().parseError(e1.sourceStart, e1.sourceEnd,
+// new char[0], "throws", new String[] {":"});
+// }
+// }
+
+ private Pointcut getPointcut() {
+ if (pointcutDesignator == null) {
+ return Pointcut.makeMatchesNothing(Pointcut.RESOLVED);
+ } else {
+ return pointcutDesignator.getPointcut();
+ }
+ }
+
+
+ public ResolvedPointcutDefinition makeResolvedPointcutDefinition() {
+ //System.out.println("pc: " + getPointcut());
+ return new ResolvedPointcutDefinition(
+ EclipseWorld.fromBinding(this.binding.declaringClass),
+ this.modifiers, // & ~AccNative,
+ new String(selector),
+ EclipseWorld.fromBindings(this.binding.parameters),
+ getPointcut());
+ }
+
+
+ public AjAttribute makeAttribute() {
+ return new AjAttribute.PointcutDeclarationAttribute(makeResolvedPointcutDefinition());
+// return new Attribute() {
+// public char[] getAttributeName() { return ResolvedPointcutDefinition.AttributeName.toCharArray(); }
+// public void writeTo(DataOutputStream s) throws IOException {
+// makeResolvedPointcut().writeAttribute(s);
+// }
+// };
+ }
+
+ /**
+ * A pointcut declaration exists in a classfile only as an attibute on the
+ * class. Unlike advice and inter-type declarations, it has no corresponding
+ * method.
+ */
+ public void generateCode(ClassScope classScope, ClassFile classFile) {
+ if (ignoreFurtherInvestigation) return ;
+ classFile.extraAttributes.add(new EclipseAttributeAdapter(makeAttribute()));
+ return;
+ }
+
+
+
+// public boolean finishResolveTypes(SourceTypeBinding sourceTypeBinding) {
+// if (!super.finishResolveTypes(sourceTypeBinding)) return false;
+// if (pointcutDesignator != null) {
+// return pointcutDesignator.finishResolveTypes(this, this.binding, arguments.length, sourceTypeBinding);
+// } else {
+// return true;
+// }
+// }
+
+ public String toString(int tab) {
+ StringBuffer buf = new StringBuffer();
+ buf.append(tabString(tab));
+ if (modifiers != 0) {
+ buf.append(modifiersString(modifiers));
+ }
+
+// if (modifiers != AccNative) {
+// buf.append(modifiersString(modifiers & ~AccNative));
+// }
+
+ buf.append("pointcut ");
+ buf.append(new String(selector));
+ buf.append("(");
+ if (arguments != null) {
+ for (int i = 0; i < arguments.length; i++) {
+ if (i > 0) buf.append(", ");
+ buf.append(arguments[i].toString(0));
+ };
+ };
+ buf.append("): ");
+
+ buf.append(getPointcut());
+
+ buf.append(";");
+ return buf.toString();
+ }
+
+ public void parseStatements(
+ Parser parser,
+ CompilationUnitDeclaration unit) {
+ if (pointcutDesignator == null) {
+ //XXXthrow new RuntimeException("unimplemented");
+ } else {
+ // do nothing
+ }
+ }
+
+ public void postParse(TypeDeclaration typeDec) {
+ if (arguments == null) arguments = new Argument[0];
+ if (pointcutDesignator == null) return; //XXX
+ pointcutDesignator.postParse(typeDec, this);
+ }
+
+ public void resolveStatements(ClassScope upperScope) {
+ if (isAbstract()) this.modifiers |= AccSemicolonBody;
+
+ if (binding == null || ignoreFurtherInvestigation) return;
+
+ if (pointcutDesignator != null) {
+ pointcutDesignator.finishResolveTypes(this, this.binding, arguments.length,
+ upperScope.referenceContext.binding);
+ }
+
+
+ super.resolveStatements(upperScope);
+ }
+
+}
diff --git a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/PointcutDesignator.java b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/PointcutDesignator.java
new file mode 100644
index 000000000..bcb0fe1ea
--- /dev/null
+++ b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/PointcutDesignator.java
@@ -0,0 +1,88 @@
+/* *******************************************************************
+ * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC).
+ * All rights reserved.
+ * This program and the accompanying materials are made available
+ * under the terms of the Common Public License v1.0
+ * which accompanies this distribution and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * Xerox/PARC initial implementation
+ * ******************************************************************/
+
+
+package org.aspectj.ajdt.internal.compiler.ast;
+
+import java.io.*;
+import java.util.List;
+
+import org.aspectj.ajdt.internal.compiler.lookup.*;
+import org.aspectj.ajdt.internal.compiler.lookup.EclipseWorld;
+import org.aspectj.weaver.*;
+import org.aspectj.weaver.patterns.*;
+import org.aspectj.weaver.patterns.FormalBinding;
+import org.eclipse.jdt.internal.compiler.ast.*;
+import org.eclipse.jdt.internal.compiler.lookup.*;
+import org.eclipse.jdt.internal.compiler.parser.Parser;
+
+public class PointcutDesignator extends AstNode {
+ private Pointcut pointcut;
+ private PseudoTokens tokens; //XXX redundant
+ private boolean isError = false;
+
+ public PointcutDesignator(Parser parser, PseudoTokens tokens) {
+ super();
+ sourceStart = tokens.sourceStart;
+ sourceEnd = tokens.sourceEnd;
+ this.tokens = tokens;
+
+ Pointcut pc = tokens.parsePointcut(parser);
+ if (pc.toString().equals("")) { //??? is this a good signal
+ isError = true;
+ }
+ pointcut = pc;
+ }
+
+ public void postParse(TypeDeclaration typeDec, MethodDeclaration enclosingDec) {
+ tokens.postParse(typeDec, enclosingDec);
+ }
+
+
+
+ public String toString(int tab) {
+ if (pointcut == null) return "<pcd>";
+ return pointcut.toString();
+ }
+
+ public boolean finishResolveTypes(final AbstractMethodDeclaration dec, MethodBinding method, final int baseArgumentCount, SourceTypeBinding sourceTypeBinding) {
+ //System.err.println("resolving: " + this);
+ //Thread.currentThread().dumpStack();
+ //XXX why do we need this test
+ if (pointcut.state == Pointcut.RESOLVED) return true;
+
+ TypeBinding[] parameters = method.parameters;
+ Argument[] arguments = dec.arguments;
+
+ FormalBinding[] bindings = new FormalBinding[baseArgumentCount];
+ for (int i = 0, len = baseArgumentCount; i < len; i++) {
+ Argument arg = arguments[i];
+ String name = new String(arg.name);
+ TypeX type = EclipseWorld.fromBinding(parameters[i]);
+ bindings[i] = new FormalBinding(type, name, i, arg.sourceStart, arg.sourceEnd, "unknown");
+ }
+
+ EclipseScope scope = new EclipseScope(bindings, dec.scope);
+
+ pointcut = pointcut.resolve(scope);
+ return true;
+ }
+
+ public Pointcut getPointcut() {
+ return pointcut;
+ }
+
+ public boolean isError() {
+ return isError;
+ }
+
+}
diff --git a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/Proceed.java b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/Proceed.java
new file mode 100644
index 000000000..541184931
--- /dev/null
+++ b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/Proceed.java
@@ -0,0 +1,123 @@
+/* *******************************************************************
+ * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC).
+ * All rights reserved.
+ * This program and the accompanying materials are made available
+ * under the terms of the Common Public License v1.0
+ * which accompanies this distribution and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * Xerox/PARC initial implementation
+ * ******************************************************************/
+
+
+package org.aspectj.ajdt.internal.compiler.ast;
+
+import org.aspectj.weaver.AdviceKind;
+import org.eclipse.jdt.internal.compiler.ast.*;
+import org.eclipse.jdt.internal.compiler.ast.MessageSend;
+import org.eclipse.jdt.internal.compiler.impl.ReferenceContext;
+import org.eclipse.jdt.internal.compiler.lookup.*;
+import org.eclipse.jdt.internal.compiler.lookup.MethodBinding;
+
+
+public class Proceed extends MessageSend {
+ public Proceed(MessageSend parent) {
+ super();
+
+ this.receiver = parent.receiver;
+ this.selector = parent.selector;
+ this.arguments = parent.arguments;
+ this.binding = parent.binding;
+ this.codegenBinding = parent.codegenBinding;
+
+ this.nameSourcePosition = parent.nameSourcePosition;
+ this.receiverType = parent.receiverType;
+ this.qualifyingType = qualifyingType;
+
+ this.sourceStart = parent.sourceStart;
+ this.sourceEnd = parent.sourceEnd;
+ }
+
+ public TypeBinding resolveType(BlockScope scope) {
+ // find out if I'm really in an around body or not
+ //??? there is a small performance issue here
+ AdviceDeclaration aroundDecl = findEnclosingAround(scope);
+
+ if (aroundDecl == null) {
+ return super.resolveType(scope);
+ }
+
+
+
+ constant = NotAConstant;
+ binding = codegenBinding = aroundDecl.proceedMethodBinding;
+
+ this.qualifyingType = this.receiverType = binding.declaringClass;
+
+ int baseArgCount = 0;
+ if (arguments != null) {
+ baseArgCount = arguments.length;
+ Expression[] newArguments = new Expression[baseArgCount + 1];
+ System.arraycopy(arguments, 0, newArguments, 0, baseArgCount);
+ arguments = newArguments;
+ } else {
+ arguments = new Expression[1];
+ }
+
+ arguments[baseArgCount] = AstUtil.makeLocalVariableReference(aroundDecl.extraArgument.binding);
+
+ int declaredParameterCount = aroundDecl.getDeclaredParameterCount();
+ if (baseArgCount < declaredParameterCount) {
+ scope.problemReporter().signalError(this.sourceStart, this.sourceEnd,
+ "too few arguments to proceed, expected " + declaredParameterCount);
+ aroundDecl.ignoreFurtherInvestigation = true;
+ return null; //binding.returnType;
+ }
+
+ if (baseArgCount > declaredParameterCount) {
+ scope.problemReporter().signalError(this.sourceStart, this.sourceEnd,
+ "too many arguments to proceed, expected " + declaredParameterCount);
+ aroundDecl.ignoreFurtherInvestigation = true;
+ return null; //binding.returnType;
+ }
+
+
+ for (int i=0, len=arguments.length; i < len; i++) {
+ Expression arg = arguments[i];
+ TypeBinding argType = arg.resolveType(scope);
+ if (argType != null) {
+ TypeBinding paramType = binding.parameters[i];
+ if (!scope.areTypesCompatible(argType, paramType)) {
+ scope.problemReporter().typeMismatchError(argType, paramType, arg);
+ }
+ arg.implicitWidening(binding.parameters[i], argType);
+ }
+ }
+
+
+ return binding.returnType;
+ }
+
+ private AdviceDeclaration findEnclosingAround(Scope scope) {
+ if (scope == null) return null;
+
+ if (scope instanceof MethodScope) {
+ MethodScope methodScope = (MethodScope)scope;
+ ReferenceContext context = methodScope.referenceContext;
+ if (context instanceof AdviceDeclaration) {
+ AdviceDeclaration adviceDecl = (AdviceDeclaration)context;
+ if (adviceDecl.kind == AdviceKind.Around) {
+ return adviceDecl;
+ } else {
+ return null;
+ }
+ }
+ }
+
+ return findEnclosingAround(scope.parent);
+ }
+
+
+
+}
diff --git a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/PseudoToken.java b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/PseudoToken.java
new file mode 100644
index 000000000..6414c8879
--- /dev/null
+++ b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/PseudoToken.java
@@ -0,0 +1,85 @@
+/* *******************************************************************
+ * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC).
+ * All rights reserved.
+ * This program and the accompanying materials are made available
+ * under the terms of the Common Public License v1.0
+ * which accompanies this distribution and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * Xerox/PARC initial implementation
+ * ******************************************************************/
+
+
+package org.aspectj.ajdt.internal.compiler.ast;
+
+import org.aspectj.weaver.patterns.*;
+import org.eclipse.jdt.internal.compiler.ast.*;
+import org.eclipse.jdt.internal.compiler.ast.AstNode;
+import org.eclipse.jdt.internal.compiler.parser.Parser;
+
+/**
+ */
+public class PseudoToken extends AstNode implements IToken {
+ public String value;
+ public boolean isIdentifier;
+ public String literalKind = null;
+ public Parser parser;
+ /**
+ * Constructor for PointcutDesignatorToken.
+ */
+ public PseudoToken(Parser parser, String value, boolean isIdentifier) {
+ this.parser = parser;
+ this.value = value;
+ this.isIdentifier = isIdentifier;
+ }
+
+ public String toString(int tab) {
+ return "<" + value + "@" + getStart() + ":" + getEnd() + ">";
+ }
+ /**
+ * @see org.aspectj.weaver.patterns.IToken#getString()
+ */
+ public String getString() {
+ return value;
+ }
+
+ /**
+ * @see org.aspectj.weaver.patterns.IToken#isIdentifier()
+ */
+ public boolean isIdentifier() {
+ return isIdentifier;
+ }
+
+ /**
+ * returns null if this isn't a literal
+ */
+ public String getLiteralKind() {
+ return literalKind;
+ }
+
+ public Pointcut maybeGetParsedPointcut() {
+ return null;
+ }
+
+
+ public int getStart() {
+ return sourceStart;
+ }
+
+ /**
+ *
+ */
+ public int getEnd() {
+ return sourceEnd;
+ }
+
+ public String getFileName() {
+ return "unknown";
+ }
+
+ public void postParse(TypeDeclaration typeDec, MethodDeclaration enclosingDec) {
+ // nothing to do typically
+ }
+
+}
diff --git a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/PseudoTokens.java b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/PseudoTokens.java
new file mode 100644
index 000000000..be578dfe5
--- /dev/null
+++ b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/PseudoTokens.java
@@ -0,0 +1,147 @@
+/* *******************************************************************
+ * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC).
+ * All rights reserved.
+ * This program and the accompanying materials are made available
+ * under the terms of the Common Public License v1.0
+ * which accompanies this distribution and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * Xerox/PARC initial implementation
+ * ******************************************************************/
+
+
+package org.aspectj.ajdt.internal.compiler.ast;
+
+import java.io.*;
+import java.util.*;
+
+
+import org.aspectj.weaver.*;
+import org.aspectj.weaver.patterns.*;
+import org.eclipse.jdt.internal.compiler.*;
+import org.eclipse.jdt.internal.compiler.ast.*;
+import org.eclipse.jdt.internal.compiler.ast.AstNode;
+import org.eclipse.jdt.internal.compiler.lookup.*;
+import org.eclipse.jdt.internal.compiler.parser.Parser;
+import org.eclipse.jdt.internal.compiler.problem.*;
+
+
+public class PseudoTokens extends AstNode {
+ BasicTokenSource tokenSource;
+ PseudoToken[] tokens; //XXX this is redundant with the field above
+ String endToken;
+
+
+ public PseudoTokens(PseudoToken[] tokens, ISourceContext sourceContext) {
+ super();
+ this.tokens = tokens;
+ this.tokenSource = new BasicTokenSource(tokens, sourceContext);
+ endToken = tokens[tokens.length-1].getString();
+ sourceStart = tokens[0].sourceStart;
+ sourceEnd = tokens[tokens.length-2].sourceEnd;
+ }
+
+ public Pointcut parsePointcut(Parser parser) {
+ PatternParser patternParser = new PatternParser(tokenSource);
+ try {
+ Pointcut ret = patternParser.parsePointcut();
+ checkEof(parser);
+ return ret;
+ } catch (ParserException pe) {
+ reportError(parser, pe);
+ return Pointcut.makeMatchesNothing(Pointcut.SYMBOLIC);
+ }
+ }
+
+ private void checkEof(Parser parser) {
+ IToken last = tokenSource.next();
+ if (tokenSource.next() != IToken.EOF) {
+ parser.problemReporter().parseError(last.getStart(), last.getEnd(),
+ last.getString().toCharArray(),
+ last.getString(),
+ new String[] {endToken});
+ }
+ }
+
+
+ private void reportError(Parser parser, ParserException pe) {
+ IHasPosition tok = pe.getLocation();
+ int start, end;
+ if (tok == IToken.EOF) {
+ start = sourceEnd+1;
+ end = sourceEnd+1;
+ } else {
+ start = tok.getStart();
+ end = tok.getEnd();
+ }
+ String found = "<unknown>";
+ if (tok instanceof IToken) {
+ found = ((IToken)tok).getString();
+ }
+
+ parser.problemReporter().parseError(start, end,
+ found.toCharArray(),
+ found,
+ new String[] {pe.getMessage()});
+ }
+
+
+ public TypePattern maybeParseDominatesPattern(Parser parser) {
+ PatternParser patternParser = new PatternParser(tokenSource);
+ try {
+ if (patternParser.maybeEatIdentifier("dominates")) {
+ // there is no eof check here
+ return patternParser.parseTypePattern();
+ } else {
+ return null;
+ }
+ } catch (ParserException pe) {
+ reportError(parser, pe);
+ return null;
+ }
+ }
+
+
+ public PerClause parsePerClause(Parser parser) {
+ PatternParser patternParser = new PatternParser(tokenSource);
+ try {
+ PerClause ret = patternParser.maybeParsePerClause();
+ checkEof(parser);
+ if (ret == null) return new PerSingleton();
+ else return ret;
+ } catch (ParserException pe) {
+ reportError(parser, pe);
+ return new PerSingleton();
+ }
+
+ }
+
+
+// public TypePattern parseTypePattern(Parser parser) {
+// }
+//
+ public Declare parseDeclare(Parser parser) {
+ PatternParser patternParser = new PatternParser(tokenSource);
+ try {
+ Declare ret = patternParser.parseDeclare();
+ checkEof(parser);
+ return ret;
+ } catch (ParserException pe) {
+ reportError(parser, pe);
+ return null;
+ }
+ }
+
+
+ public void postParse(TypeDeclaration typeDec, MethodDeclaration enclosingDec) {
+ for (int i=0, len=tokens.length; i < len; i++) {
+ tokens[i].postParse(typeDec, enclosingDec);
+ }
+ }
+
+
+ public String toString(int tab) {
+ return tokenSource.toString();
+ }
+}
diff --git a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/SuperFixerVisitor.java b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/SuperFixerVisitor.java
new file mode 100644
index 000000000..c1747778a
--- /dev/null
+++ b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/SuperFixerVisitor.java
@@ -0,0 +1,68 @@
+/* *******************************************************************
+ * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC).
+ * All rights reserved.
+ * This program and the accompanying materials are made available
+ * under the terms of the Common Public License v1.0
+ * which accompanies this distribution and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * Xerox/PARC initial implementation
+ * ******************************************************************/
+
+
+package org.aspectj.ajdt.internal.compiler.ast;
+
+import java.util.*;
+import java.util.Arrays;
+
+import org.aspectj.weaver.*;
+import org.aspectj.weaver.ShadowMunger;
+import org.eclipse.jdt.internal.compiler.AbstractSyntaxTreeVisitorAdapter;
+import org.eclipse.jdt.internal.compiler.ast.*;
+import org.eclipse.jdt.internal.compiler.lookup.*;
+
+/**
+ * Takes a method that already has the three extra parameters
+ * thisJoinPointStaticPart, thisJoinPoint and thisEnclosingJoinPointStaticPart
+ */
+
+public class SuperFixerVisitor extends AbstractSyntaxTreeVisitorAdapter {
+ Set superMethodsCalled = new HashSet();
+ AbstractMethodDeclaration method;
+ ReferenceBinding targetClass;
+
+ SuperFixerVisitor(AbstractMethodDeclaration method, ReferenceBinding targetClass) {
+ this.method = method;
+ this.targetClass = targetClass;
+ }
+
+
+ //XXX does this walk into inners
+ public void endVisit(MessageSend call, BlockScope scope) {
+ //System.out.println("endVisit: " + call);
+ // an error has already occurred
+ if (call.codegenBinding == null) return;
+
+ if (!call.isSuperAccess() || call.binding.isStatic()) return;
+
+ call.receiver = new ThisReference();
+
+ MethodBinding superBinding = call.codegenBinding;
+
+ char[] accessName = AstUtil.makeAjcMangledName(
+ ResolvedTypeMunger.SUPER_DISPATCH_NAME.toCharArray(), targetClass, superBinding.selector
+ );
+
+ //??? do we want these to be unique
+ MethodBinding superAccessBinding =
+ new MethodBinding(AstNode.AccPublic, accessName,
+ superBinding.returnType, superBinding.parameters, superBinding.thrownExceptions,
+ targetClass);
+
+ call.codegenBinding = superAccessBinding;
+
+ superMethodsCalled.add(superBinding);
+
+ }
+}
diff --git a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/ThisJoinPointVisitor.java b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/ThisJoinPointVisitor.java
new file mode 100644
index 000000000..989d9123d
--- /dev/null
+++ b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/ThisJoinPointVisitor.java
@@ -0,0 +1,224 @@
+/* *******************************************************************
+ * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC).
+ * All rights reserved.
+ * This program and the accompanying materials are made available
+ * under the terms of the Common Public License v1.0
+ * which accompanies this distribution and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * Xerox/PARC initial implementation
+ * ******************************************************************/
+
+
+package org.aspectj.ajdt.internal.compiler.ast;
+
+import java.util.Arrays;
+
+import org.aspectj.weaver.*;
+import org.aspectj.weaver.ShadowMunger;
+import org.eclipse.jdt.internal.compiler.AbstractSyntaxTreeVisitorAdapter;
+import org.eclipse.jdt.internal.compiler.ast.*;
+import org.eclipse.jdt.internal.compiler.lookup.*;
+
+/**
+ * Takes a method that already has the three extra parameters
+ * thisJoinPointStaticPart, thisJoinPoint and thisEnclosingJoinPointStaticPart
+ */
+
+public class ThisJoinPointVisitor extends AbstractSyntaxTreeVisitorAdapter {
+ boolean needsDynamic = false;
+ boolean needsStatic = false;
+ boolean needsStaticEnclosing = false;
+ boolean hasEffectivelyStaticRef = false;
+
+ LocalVariableBinding thisJoinPointDec;
+ LocalVariableBinding thisJoinPointStaticPartDec;
+ LocalVariableBinding thisEnclosingJoinPointStaticPartDec;
+
+ LocalVariableBinding thisJoinPointDecLocal;
+ LocalVariableBinding thisJoinPointStaticPartDecLocal;
+ LocalVariableBinding thisEnclosingJoinPointStaticPartDecLocal;
+
+ boolean replaceEffectivelyStaticRefs = false;
+
+ AbstractMethodDeclaration method;
+
+ ThisJoinPointVisitor(AbstractMethodDeclaration method) {
+ this.method = method;
+ int index = method.arguments.length - 3;
+
+ thisJoinPointStaticPartDecLocal = method.scope.locals[index];
+ thisJoinPointStaticPartDec = method.arguments[index++].binding;
+ thisJoinPointDecLocal = method.scope.locals[index];
+ thisJoinPointDec = method.arguments[index++].binding;
+ thisEnclosingJoinPointStaticPartDecLocal = method.scope.locals[index];
+ thisEnclosingJoinPointStaticPartDec = method.arguments[index++].binding;
+ }
+
+ public void computeJoinPointParams() {
+ // walk my body to see what is needed
+ method.traverse(this, (ClassScope) null);
+
+ //??? add support for option to disable this optimization
+ //System.err.println("check: "+ hasEffectivelyStaticRef + ", " + needsDynamic);
+ if (hasEffectivelyStaticRef && !needsDynamic) {
+ // replace effectively static refs with thisJoinPointStaticPart
+ replaceEffectivelyStaticRefs = true;
+ needsStatic = true;
+ method.traverse(this, (ClassScope) null);
+ }
+ }
+
+ boolean isRef(NameReference ref, Binding binding) {
+ return ref.binding == binding;
+ }
+
+ boolean isRef(Expression expr, Binding binding) {
+ //System.err.println("isRef: " + expr + ", " + binding);
+ return expr != null
+ && expr instanceof NameReference
+ && isRef((NameReference) expr, binding);
+ }
+
+ public void endVisit(SingleNameReference ref, BlockScope scope) {
+ if (isRef(ref, thisJoinPointDec))
+ needsDynamic = true;
+ else if (isRef(ref, thisJoinPointStaticPartDec))
+ needsStatic = true;
+ else if (isRef(ref, thisEnclosingJoinPointStaticPartDec))
+ needsStaticEnclosing = true;
+ }
+
+ // public void checkAndFix(ASTObject body) {
+ // this.process(body);
+ // if (needsFakeStatic && !needsDynamic) {
+ // if (!this.getCompiler().getOptions().noMetaJoinPointOptimization) {
+ // makeFakeStatics = true;
+ // needsStatic = true;
+ // this.process(body);
+ // } else {
+ // needsDynamic = true;
+ // }
+ // }
+ // }
+
+ boolean canTreatAsStatic(String id) {
+ return id.equals("toString")
+ || id.equals("toShortString")
+ || id.equals("toLongString")
+ || id.equals("getKind")
+ || id.equals("getSignature")
+ || id.equals("getSourceLocation")
+ || id.equals("getStaticPart");
+ }
+
+ // boolean canTreatAsStatic(VarExpr varExpr) {
+ // ASTObject parent = varExpr.getParent();
+ // if (parent instanceof CallExpr) {
+ // Method calledMethod = ((CallExpr)parent).getMethod();
+ // return canTreatAsStatic(calledMethod);
+ //
+ // //??? should add a case here to catch
+ // //??? tjp.getEnclosingExecutionJoinPoint().STATIC_METHOD()
+ // } else if (parent instanceof BinopExpr) {
+ // BinopExpr binop = (BinopExpr)parent;
+ // if (binop.getType().isEquivalent(this.getTypeManager().getStringType())) {
+ // return true;
+ // } else {
+ // return false;
+ // }
+ // } else {
+ // return false;
+ // }
+ // }
+
+ boolean inBlockThatCantRun = false;
+
+ public boolean visit(MessageSend call, BlockScope scope) {
+ Expression receiver = call.receiver;
+ if (isRef(receiver, thisJoinPointDec)) {
+ if (canTreatAsStatic(new String(call.selector))) {
+ if (replaceEffectivelyStaticRefs) {
+ replaceEffectivelyStaticRef(call);
+ } else {
+ //System.err.println("has static reg");
+ hasEffectivelyStaticRef = true;
+ if (call.arguments != null) {
+ int argumentsLength = call.arguments.length;
+ for (int i = 0; i < argumentsLength; i++)
+ call.arguments[i].traverse(this, scope);
+ }
+ return false;
+ }
+ }
+ }
+
+ return super.visit(call, scope);
+ }
+
+ private void replaceEffectivelyStaticRef(MessageSend call) {
+ //System.err.println("replace static ref");
+ NameReference receiver = (NameReference) call.receiver;
+ receiver.binding = thisJoinPointStaticPartDecLocal; //thisJoinPointStaticPartDec;
+ receiver.codegenBinding = thisJoinPointStaticPartDecLocal;
+
+ call.binding.declaringClass =
+ (ReferenceBinding) thisJoinPointStaticPartDec.type;
+ }
+
+ public int removeUnusedExtraArguments() {
+ int extraArgumentFlags = 0;
+
+ this.computeJoinPointParams();
+ MethodBinding binding = method.binding;
+
+
+ int index = binding.parameters.length - 3;
+ if (needsStaticEnclosing) {
+ extraArgumentFlags |= Advice.ThisEnclosingJoinPointStaticPart;
+ } else {
+ removeParameter(index+2);
+ }
+
+ if (needsDynamic) {
+ extraArgumentFlags |= Advice.ThisJoinPoint;
+ } else {
+ removeParameter(index+1);
+ }
+
+ if (needsStatic) {
+ extraArgumentFlags |= Advice.ThisJoinPointStaticPart;
+ } else {
+ removeParameter(index+0);
+ }
+
+ return extraArgumentFlags;
+ }
+
+ private void removeParameter(int indexToRemove) {
+ TypeBinding[] parameters = method.binding.parameters;
+ method.scope.locals = removeLocalBinding(indexToRemove, method.scope.locals);
+ method.binding.parameters = removeParameter(indexToRemove, method.binding.parameters);
+ }
+
+
+ private static TypeBinding[] removeParameter(int index, TypeBinding[] bindings) {
+ int len = bindings.length;
+ TypeBinding[] ret = new TypeBinding[len-1];
+ System.arraycopy(bindings, 0, ret, 0, index);
+ System.arraycopy(bindings, index+1, ret, index, len-index-1);
+ return ret;
+ }
+
+ private static LocalVariableBinding[] removeLocalBinding(int index, LocalVariableBinding[] bindings) {
+ int len = bindings.length;
+ //??? for performance we should do this in-place
+ LocalVariableBinding[] ret = new LocalVariableBinding[len-1];
+ System.arraycopy(bindings, 0, ret, 0, index);
+ System.arraycopy(bindings, index+1, ret, index, len-index-1);
+ return ret;
+ }
+
+
+}
diff --git a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/AjLookupEnvironment.java b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/AjLookupEnvironment.java
new file mode 100644
index 000000000..e09f859fc
--- /dev/null
+++ b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/AjLookupEnvironment.java
@@ -0,0 +1,201 @@
+/* *******************************************************************
+ * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC).
+ * All rights reserved.
+ * This program and the accompanying materials are made available
+ * under the terms of the Common Public License v1.0
+ * which accompanies this distribution and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * Xerox/PARC initial implementation
+ * ******************************************************************/
+
+
+package org.aspectj.ajdt.internal.compiler.lookup;
+
+import java.util.*;
+
+import org.aspectj.ajdt.internal.compiler.ast.*;
+import org.aspectj.bridge.MessageUtil;
+import org.aspectj.weaver.*;
+import org.aspectj.weaver.patterns.*;
+import org.eclipse.jdt.internal.compiler.ast.*;
+import org.eclipse.jdt.internal.compiler.env.INameEnvironment;
+import org.eclipse.jdt.internal.compiler.impl.*;
+import org.eclipse.jdt.internal.compiler.lookup.*;
+import org.eclipse.jdt.internal.compiler.problem.ProblemReporter;
+
+public class AjLookupEnvironment extends LookupEnvironment {
+ public EclipseWorld world = null;
+
+ public AjLookupEnvironment(
+ ITypeRequestor typeRequestor,
+ CompilerOptions options,
+ ProblemReporter problemReporter,
+ INameEnvironment nameEnvironment) {
+ super(typeRequestor, options, problemReporter, nameEnvironment);
+ }
+
+ //XXX figure out if we can do this through super or not
+ //XXX otherwise duplicates some of super's code
+ public void completeTypeBindings() {
+ stepCompleted = BUILD_TYPE_HIERARCHY;
+
+ for (int i = lastCompletedUnitIndex + 1; i <= lastUnitIndex; i++) {
+ units[i].scope.checkAndSetImports();
+ }
+ stepCompleted = CHECK_AND_SET_IMPORTS;
+
+ for (int i = lastCompletedUnitIndex + 1; i <= lastUnitIndex; i++) {
+ units[i].scope.connectTypeHierarchy();
+ }
+ stepCompleted = CONNECT_TYPE_HIERARCHY;
+
+ // collect inter-type declarations as well
+ for (int i = lastCompletedUnitIndex + 1; i <= lastUnitIndex; i++) {
+ units[i].scope.buildFieldsAndMethods();
+ }
+
+ // need to build inter-type declarations for all AspectDeclarations at this point
+ for (int i = lastCompletedUnitIndex + 1; i <= lastUnitIndex; i++) {
+ SourceTypeBinding[] b = units[i].scope.topLevelTypes;
+ for (int j = 0; j < b.length; j++) {
+ buildInterTypeAndPerClause(b[j].scope);
+ }
+ }
+ //??? do we need a new stepCompleted
+
+ // now do weaving
+ Collection typeMungers = world.getTypeMungers();
+ Collection declareParents = world.getDeclareParents();
+ for (int i = lastCompletedUnitIndex + 1; i <= lastUnitIndex; i++) {
+ weaveInterTypeDeclarations(units[i].scope, typeMungers, declareParents);
+ units[i] = null; // release unnecessary reference to the parsed unit
+ }
+
+ stepCompleted = BUILD_FIELDS_AND_METHODS;
+ lastCompletedUnitIndex = lastUnitIndex;
+ }
+
+ private void buildInterTypeAndPerClause(ClassScope s) {
+ TypeDeclaration dec = s.referenceContext;
+ if (dec instanceof AspectDeclaration) {
+ ((AspectDeclaration)dec).buildInterTypeAndPerClause(s);
+ }
+
+ SourceTypeBinding sourceType = s.referenceContext.binding;
+
+ ReferenceBinding[] memberTypes = sourceType.memberTypes;
+ for (int i = 0, length = memberTypes.length; i < length; i++) {
+ buildInterTypeAndPerClause(((SourceTypeBinding) memberTypes[i]).scope);
+ }
+ }
+
+
+ private void weaveInterTypeDeclarations(CompilationUnitScope unit, Collection typeMungers, Collection declareParents) {
+ for (int i = 0, length = unit.topLevelTypes.length; i < length; i++)
+ weaveInterTypeDeclarations(unit.topLevelTypes[i].scope, typeMungers, declareParents);
+
+ //System.err.println("done with inter types");
+ }
+
+ private void weaveInterTypeDeclarations(ClassScope scope, Collection typeMungers, Collection declareParents) {
+ //System.err.println("weaving: " + scope);
+ SourceTypeBinding sourceType = scope.referenceContext.binding;
+ ResolvedTypeX onType = world.fromEclipse(sourceType);
+ for (Iterator i = declareParents.iterator(); i.hasNext();) {
+ doDeclareParents((DeclareParents)i.next(), scope);
+ }
+
+ for (Iterator i = typeMungers.iterator(); i.hasNext();) {
+ EclipseTypeMunger munger = (EclipseTypeMunger) i.next();
+ //System.out.println("weaving: " + munger);
+ //if (munger.match(scope))
+ if (munger.matches(onType)) {
+ onType.addInterTypeMunger(munger);
+ }
+ }
+
+ for (Iterator i = onType.getInterTypeMungers().iterator(); i.hasNext();) {
+ EclipseTypeMunger munger = (EclipseTypeMunger) i.next();
+ munger.munge(scope);
+ }
+
+
+
+ ReferenceBinding[] memberTypes = sourceType.memberTypes;
+ for (int i = 0, length = memberTypes.length; i < length; i++) {
+ weaveInterTypeDeclarations(((SourceTypeBinding) memberTypes[i]).scope, typeMungers, declareParents);
+ }
+ }
+
+ private void doDeclareParents(DeclareParents declareParents, ClassScope scope) {
+ if (declareParents.match(world.fromEclipse(scope.referenceContext.binding))) {
+ TypePatternList l = declareParents.getParents();
+ for (int i=0, len=l.size(); i < len; i++) {
+ addParent(declareParents, scope, l.get(i));
+ }
+ }
+ }
+
+ private void addParent(DeclareParents declareParents, ClassScope scope, TypePattern typePattern) {
+ SourceTypeBinding sourceType = scope.referenceContext.binding;
+ if (!typePattern.assertExactType(world.getMessageHandler())) return;
+ TypeX iType = typePattern.getExactType();
+// if (iType == null) {
+// throw new RuntimeException("yikes: " + typePattern);
+// }
+ //if (iType == ResolvedTypeX.MISSING || iType == null) return;
+ ReferenceBinding b = (ReferenceBinding)world.makeTypeBinding(iType); //"
+
+ if (b.isClass()) {
+ if (sourceType.isInterface()) {
+ world.getMessageHandler().handleMessage(MessageUtil.error(
+ "interface can not extend a class", declareParents.getSourceLocation()
+ ));
+ // how to handle xcutting errors???
+ }
+
+ if (sourceType == b || sourceType.isSuperclassOf(b)) {
+ world.getMessageHandler().handleMessage(MessageUtil.error(
+ "class can not extend itself", declareParents.getSourceLocation()
+ ));
+ return;
+ }
+ sourceType.superclass = b;
+ } else {
+ //??? it's not considered an error to extend yourself, nothing happens
+ if (sourceType.equals(b)) {
+ return;
+ }
+
+ if (sourceType.isInterface() && b.implementsInterface(sourceType, true)) {
+ world.getMessageHandler().handleMessage(MessageUtil.error(
+ "interface can not extend itself", declareParents.getSourceLocation()
+ ));
+ return;
+ }
+ if (sourceType == b || b.isSuperclassOf(sourceType)) return;
+ ReferenceBinding[] oldI = sourceType.superInterfaces;
+ ReferenceBinding[] newI;
+ if (oldI == null) {
+ newI = new ReferenceBinding[1];
+ newI[0] = b;
+ } else {
+ int n = oldI.length;
+ newI = new ReferenceBinding[n+1];
+ System.arraycopy(oldI, 0, newI, 0, n);
+ newI[n] = b;
+ }
+ sourceType.superInterfaces = newI;
+ }
+
+ }
+
+ private TypeReference makeReference(ExactTypePattern e) {
+ return new SingleTypeReference(e.getType().getName().toCharArray(),
+ AstUtil.makeLongPos(e.getStart(), e.getEnd()));
+ }
+
+
+}
diff --git a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/AjTypeConstants.java b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/AjTypeConstants.java
new file mode 100644
index 000000000..fdb53c2a2
--- /dev/null
+++ b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/AjTypeConstants.java
@@ -0,0 +1,68 @@
+/* *******************************************************************
+ * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC).
+ * All rights reserved.
+ * This program and the accompanying materials are made available
+ * under the terms of the Common Public License v1.0
+ * which accompanies this distribution and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * Xerox/PARC initial implementation
+ * ******************************************************************/
+
+
+package org.aspectj.ajdt.internal.compiler.lookup;
+
+import org.eclipse.jdt.internal.compiler.ast.QualifiedTypeReference;
+import org.eclipse.jdt.internal.compiler.ast.TypeReference;
+import org.eclipse.jdt.internal.compiler.lookup.*;
+import org.eclipse.jdt.internal.compiler.lookup.Scope;
+
+public class AjTypeConstants {
+
+ public static final char[] ORG = "org".toCharArray();
+ public static final char[] ASPECTJ = "aspectj".toCharArray();
+ public static final char[] RUNTIME = "runtime".toCharArray();
+ public static final char[] LANG = "lang".toCharArray();
+ public static final char[] INTERNAL = "internal".toCharArray();
+
+ // Constant compound names
+ public static final char[][] ORG_ASPECTJ_LANG_JOINPOINT =
+ new char[][] {ORG, ASPECTJ, LANG, "JoinPoint".toCharArray()};
+
+ public static final char[][] ORG_ASPECTJ_LANG_JOINPOINT_STATICPART =
+ new char[][] {ORG, ASPECTJ, LANG, "JoinPoint".toCharArray(), "StaticPart".toCharArray()};
+
+ public static final char[][] ORG_ASPECTJ_RUNTIME_INTERNAL_AROUNDCLOSURE =
+ new char[][] {ORG, ASPECTJ, RUNTIME, INTERNAL, "AroundClosure".toCharArray()};
+
+ public static final char[][] ORG_ASPECTJ_RUNTIME_INTERNAL_CONVERSIONS =
+ new char[][] {ORG, ASPECTJ, RUNTIME, INTERNAL, "Conversions".toCharArray()};
+
+ public static TypeReference getJoinPointType() {
+ return new QualifiedTypeReference(ORG_ASPECTJ_LANG_JOINPOINT, new long[10]);
+ }
+
+ public static TypeReference getJoinPointStaticPartType() {
+ return new QualifiedTypeReference(ORG_ASPECTJ_LANG_JOINPOINT_STATICPART, new long[10]);
+ }
+
+ public static TypeReference getAroundClosureType() {
+ return new QualifiedTypeReference(ORG_ASPECTJ_RUNTIME_INTERNAL_AROUNDCLOSURE, new long[10]);
+ }
+
+ public static ReferenceBinding getConversionsType(Scope scope) {
+ return (ReferenceBinding)scope.getType(ORG_ASPECTJ_RUNTIME_INTERNAL_CONVERSIONS);
+ }
+
+ public static MethodBinding getConversionMethodToObject(Scope scope, TypeBinding fromType) {
+ String name = new String(fromType.sourceName()) + "Object";
+ return getConversionsType(scope).getMethods(name.toCharArray())[0];
+ }
+
+ public static MethodBinding getConversionMethodFromObject(Scope scope, TypeBinding toType) {
+ String name = new String(toType.sourceName()) + "Value";
+ return getConversionsType(scope).getMethods(name.toCharArray())[0];
+ }
+
+}
diff --git a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/EclipseAdvice.java b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/EclipseAdvice.java
new file mode 100644
index 000000000..41cab4c62
--- /dev/null
+++ b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/EclipseAdvice.java
@@ -0,0 +1,46 @@
+/* *******************************************************************
+ * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC).
+ * All rights reserved.
+ * This program and the accompanying materials are made available
+ * under the terms of the Common Public License v1.0
+ * which accompanies this distribution and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * Xerox/PARC initial implementation
+ * ******************************************************************/
+
+
+package org.aspectj.ajdt.internal.compiler.lookup;
+
+import org.aspectj.weaver.*;
+import org.aspectj.weaver.Advice;
+import org.aspectj.weaver.patterns.Pointcut;
+
+
+public class EclipseAdvice extends Advice {
+ public EclipseAdvice(
+ AdviceKind kind,
+ Pointcut pointcut,
+ Member signature,
+ int extraParameterFlags,
+ int start, int end, ISourceContext context) {
+
+ super(kind, pointcut, signature, extraParameterFlags, start, end, context);
+ }
+
+
+
+ public void implementOn(Shadow shadow) {
+ throw new RuntimeException("unimplemented");
+ }
+
+ public void specializeOn(Shadow shadow) {
+ throw new RuntimeException("unimplemented");
+ }
+
+ public int compareTo(Object other) {
+ throw new RuntimeException("unimplemented");
+ }
+
+}
diff --git a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/EclipseObjectType.java b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/EclipseObjectType.java
new file mode 100644
index 000000000..c483f6094
--- /dev/null
+++ b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/EclipseObjectType.java
@@ -0,0 +1,123 @@
+/* *******************************************************************
+ * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC).
+ * All rights reserved.
+ * This program and the accompanying materials are made available
+ * under the terms of the Common Public License v1.0
+ * which accompanies this distribution and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * Xerox/PARC initial implementation
+ * ******************************************************************/
+
+
+package org.aspectj.ajdt.internal.compiler.lookup;
+
+import java.util.*;
+
+import org.aspectj.ajdt.internal.compiler.ast.*;
+import org.aspectj.ajdt.internal.compiler.ast.PointcutDeclaration;
+import org.aspectj.weaver.*;
+import org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration;
+import org.eclipse.jdt.internal.compiler.lookup.*;
+
+public class EclipseObjectType extends ResolvedTypeX.Name {
+ private ReferenceBinding binding;
+
+ private ResolvedMember[] declaredPointcuts = null;
+ private ResolvedMember[] declaredMethods = null;
+ private ResolvedMember[] declaredFields = null;
+
+
+ public EclipseObjectType(String signature, EclipseWorld world, ReferenceBinding binding) {
+ super(signature, world);
+ this.binding = binding;
+ }
+
+ private EclipseWorld eclipseWorld() {
+ return (EclipseWorld)world;
+ }
+
+
+ public boolean isAspect() {
+ if (!(binding instanceof SourceTypeBinding)) return false;
+ //XXX assume SourceBinding throughout
+ return ((SourceTypeBinding)binding).scope.referenceContext instanceof AspectDeclaration;
+
+ }
+
+ public ResolvedTypeX getSuperclass() {
+ //XXX what about java.lang.Object
+ return eclipseWorld().fromEclipse(binding.superclass());
+ }
+
+ public ResolvedTypeX[] getDeclaredInterfaces() {
+ return eclipseWorld().fromEclipse(binding.superInterfaces());
+ }
+
+ public ResolvedMember[] getDeclaredFields() {
+ if (declaredFields == null) fillDeclaredMembers();
+ return declaredFields;
+ }
+
+ public ResolvedMember[] getDeclaredMethods() {
+ if (declaredMethods == null) fillDeclaredMembers();
+ return declaredMethods;
+ }
+
+ public ResolvedMember[] getDeclaredPointcuts() {
+ if (declaredPointcuts == null) fillDeclaredMembers();
+ return declaredPointcuts;
+ }
+
+ private void fillDeclaredMembers() {
+ List declaredPointcuts = new ArrayList();
+ List declaredMethods = new ArrayList();
+ List declaredFields = new ArrayList();
+
+ MethodBinding[] methods = binding.methods();
+ for (int i=0, len=methods.length; i < len; i++) {
+ MethodBinding m = methods[i];
+ AbstractMethodDeclaration amd = m.sourceMethod();
+ if (amd == null) continue; //???
+ if (amd instanceof PointcutDeclaration) {
+ PointcutDeclaration d = (PointcutDeclaration)amd;
+ declaredPointcuts.add(d.makeResolvedPointcutDefinition());
+ } else {
+ //XXX this doesn't handle advice quite right
+ declaredMethods.add(eclipseWorld().makeResolvedMember(m));
+ }
+ }
+
+ FieldBinding[] fields = binding.fields();
+ for (int i=0, len=fields.length; i < len; i++) {
+ FieldBinding f = fields[i];
+ declaredFields.add(eclipseWorld().makeResolvedMember(f));
+ }
+
+ this.declaredPointcuts = (ResolvedMember[])
+ declaredPointcuts.toArray(new ResolvedMember[declaredPointcuts.size()]);
+ this.declaredMethods = (ResolvedMember[])
+ declaredMethods.toArray(new ResolvedMember[declaredMethods.size()]);
+ this.declaredFields = (ResolvedMember[])
+ declaredFields.toArray(new ResolvedMember[declaredFields.size()]);
+ }
+
+
+ public int getModifiers() {
+ // only return the real Java modifiers, not the extra eclipse ones
+ return binding.modifiers & CompilerModifiers.AccJustFlag;
+ }
+
+ ReferenceBinding getBinding() {
+ return binding;
+ }
+
+ public String toString() {
+ return "EclipseObjectType(" + getClassName() + ")";
+ }
+ public CrosscuttingMembers collectCrosscuttingMembers() {
+ return crosscuttingMembers;
+ }
+
+}
diff --git a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/EclipseScope.java b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/EclipseScope.java
new file mode 100644
index 000000000..b77d5e99e
--- /dev/null
+++ b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/EclipseScope.java
@@ -0,0 +1,254 @@
+/* *******************************************************************
+ * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC).
+ * All rights reserved.
+ * This program and the accompanying materials are made available
+ * under the terms of the Common Public License v1.0
+ * which accompanies this distribution and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * Xerox/PARC initial implementation
+ * ******************************************************************/
+
+
+package org.aspectj.ajdt.internal.compiler.lookup;
+
+import java.util.*;
+
+import org.aspectj.weaver.*;
+import org.aspectj.weaver.patterns.*;
+import org.aspectj.bridge.*;
+import org.eclipse.jdt.internal.compiler.lookup.*;
+import org.eclipse.jdt.internal.compiler.util.CharOperation;
+
+public class EclipseScope implements IScope {
+ private Scope scope;
+ private EclipseWorld world;
+ private ResolvedTypeX enclosingType;
+ private FormalBinding[] bindings;
+
+ private String[] importedPrefixes = null;
+ private String[] importedNames = null;
+
+
+ public EclipseScope(FormalBinding[] bindings, Scope scope) {
+ this.bindings = bindings;
+
+ this.scope = scope;
+ this.world = EclipseWorld.fromScopeLookupEnvironment(scope);
+
+ this.enclosingType = world.fromEclipse(scope.enclosingSourceType());
+ }
+
+
+ public TypeX lookupType(String name, IHasPosition location) {
+ computeImports();
+
+// System.out.println("lookup: " + name + " in " +
+// Arrays.asList(importedPrefixes));
+
+ ResolvedTypeX ret = null;
+ String dotName = "." + name;
+ for (int i=0; i<importedNames.length; i++) {
+ String importedName = importedNames[i];
+ //??? can this be right
+ if (importedName.endsWith(name) &&
+ ((importedName.length() == name.length()) ||
+ (importedName.endsWith(dotName))))
+ {
+ ResolvedTypeX found = resolveVisible(importedName);
+ if (found == ResolvedTypeX.MISSING) continue;
+ if (ret != null) {
+ message(IMessage.ERROR, location,
+ "ambiguous type reference, both " + ret.getName() + " and " + importedName);
+ return ResolvedTypeX.MISSING;
+ } else {
+ ret = found;
+ }
+ }
+ }
+
+ if (ret != null) return ret;
+
+ //XXX need to handle ambiguous references here
+ for (int i=0; i<importedPrefixes.length; i++) {
+ String importedPrefix = importedPrefixes[i];
+ ResolvedTypeX tryType = resolveVisible(importedPrefix + name);
+ if (tryType != ResolvedTypeX.MISSING) {
+ return tryType;
+ }
+ }
+
+ return resolveVisible(name);
+ }
+
+
+ private ResolvedTypeX resolveVisible(String name) {
+ ResolvedTypeX found = world.resolve(TypeX.forName(name), true);
+ if (found == ResolvedTypeX.MISSING) return found;
+ if (ResolvedTypeX.isVisible(found.getModifiers(), found, enclosingType)) return found;
+ return ResolvedTypeX.MISSING;
+ }
+
+
+// public TypeX lookupType(String name, IHasPosition location) {
+// char[][] namePieces = CharOperation.splitOn('.', name.toCharArray());
+// TypeBinding binding;
+// if (namePieces.length == 1) {
+// binding = scope.getType(namePieces[0]);
+// } else {
+// binding = scope.getType(namePieces);
+// }
+//
+//
+// if (!binding.isValidBinding()) {
+// //XXX do we do this always or sometimes
+// System.err.println("error: " + binding);
+// scope.problemReporter().invalidType(EclipseWorld.astForLocation(location), binding);
+// return ResolvedTypeX.MISSING;
+// }
+// //??? do we want this too
+//// if (AstNode.isTypeUseDeprecated(binding, scope))
+//// scope.problemReporter().deprecatedType(binding, EclipseWorld.astForLocation(location));
+//
+// return EclipseWorld.fromBinding(binding);
+// }
+
+
+
+ private void computeImports() {
+ if (importedNames != null) return;
+
+ List importedNamesList = new ArrayList();
+ List importedPrefixesList = new ArrayList();
+
+
+ Scope currentScope = scope;
+ //add any enclosing types to this list
+ while (!(currentScope instanceof CompilationUnitScope)) {
+ if (currentScope == null) {
+ throw new RuntimeException("unimplemented");
+ }
+ if (currentScope instanceof ClassScope) {
+ addClassAndParentsToPrefixes(((ClassScope)currentScope).referenceType().binding, importedPrefixesList);
+ }
+ currentScope = currentScope.parent;
+ }
+
+ CompilationUnitScope cuScope = (CompilationUnitScope)currentScope;
+
+ String packageName =
+ new String(CharOperation.concatWith(cuScope.currentPackageName, '.'));
+ if (packageName.length() > 1) {
+ importedPrefixesList.add(packageName + ".");
+ }
+
+
+ ImportBinding[] imports = cuScope.imports;
+ for (int i = 0; i < imports.length; i++) {
+ ImportBinding importBinding = imports[i];
+ String importName =
+ new String(CharOperation.concatWith(importBinding.compoundName, '.'));
+
+ //XXX wrong behavior for java.util.Map.*
+ if (importBinding.onDemand) {
+ importedPrefixesList.add(importName + ".");
+ } else {
+ importedNamesList.add(importName);
+ }
+ }
+
+ TypeBinding[] topTypes = cuScope.topLevelTypes;
+ for (int i = 0; i < topTypes.length; i++) {
+ importedNamesList.add(EclipseWorld.fromBinding(topTypes[i]).getName());
+ }
+
+ importedNames =
+ (String[])importedNamesList.toArray(new String[importedNamesList.size()]);
+
+ importedPrefixes =
+ (String[])importedPrefixesList.toArray(new String[importedPrefixesList.size()]);
+ }
+
+ private void addClassAndParentsToPrefixes(
+ ReferenceBinding binding,
+ List importedPrefixesList)
+ {
+ if (binding == null) return;
+ importedPrefixesList.add(EclipseWorld.fromBinding(binding).getName()+"$");
+
+ addClassAndParentsToPrefixes(binding.superclass(), importedPrefixesList);
+ ReferenceBinding[] superinterfaces = binding.superInterfaces();
+ if (superinterfaces != null) {
+ for (int i = 0; i < superinterfaces.length; i++) {
+ addClassAndParentsToPrefixes(superinterfaces[i], importedPrefixesList);
+ }
+ }
+ }
+
+
+ public String[] getImportedNames() {
+ computeImports();
+ return importedNames;
+ }
+
+ public String[] getImportedPrefixes() {
+ computeImports();
+ return importedPrefixes;
+ }
+
+
+ //XXX add good errors when would bind to extra parameters
+ public FormalBinding lookupFormal(String name) {
+ for (int i = 0, len = bindings.length; i < len; i++) {
+ if (bindings[i].getName().equals(name)) return bindings[i];
+ }
+ return null;
+ }
+
+
+ public FormalBinding getFormal(int i) {
+ return bindings[i];
+ }
+
+ public int getFormalCount() {
+ return bindings.length;
+ }
+
+ public ISourceLocation makeSourceLocation(IHasPosition location) {
+ return new EclipseSourceLocation(scope.problemReporter().referenceContext.compilationResult(),
+ location.getStart(), location.getEnd());
+ }
+
+ public IMessageHandler getMessageHandler() {
+ return world.getMessageHandler();
+ }
+
+
+ public void message(
+ IMessage.Kind kind,
+ IHasPosition location1,
+ IHasPosition location2,
+ String message) {
+ message(kind, location1, message);
+ message(kind, location2, message);
+ }
+
+ public void message(
+ IMessage.Kind kind,
+ IHasPosition location,
+ String message) {
+ //System.out.println("message: " + message + " loc: " + makeSourceLocation(location));
+ getMessageHandler()
+ .handleMessage(new Message(message, kind, null, makeSourceLocation(location)));
+
+ }
+ public World getWorld() {
+ return world;
+ }
+
+ public ResolvedTypeX getEnclosingType() {
+ return enclosingType;
+ }
+
+}
diff --git a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/EclipseShadow.java b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/EclipseShadow.java
new file mode 100644
index 000000000..5f362ccc3
--- /dev/null
+++ b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/EclipseShadow.java
@@ -0,0 +1,132 @@
+/* *******************************************************************
+ * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC).
+ * All rights reserved.
+ * This program and the accompanying materials are made available
+ * under the terms of the Common Public License v1.0
+ * which accompanies this distribution and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * Xerox/PARC initial implementation
+ * ******************************************************************/
+
+
+package org.aspectj.ajdt.internal.compiler.lookup;
+
+import org.aspectj.ajdt.internal.compiler.ast.AdviceDeclaration;
+import org.aspectj.bridge.SourceLocation;
+import org.aspectj.weaver.*;
+import org.aspectj.weaver.ast.Var;
+import org.eclipse.jdt.internal.compiler.ast.*;
+import org.eclipse.jdt.internal.compiler.ast.AstNode;
+import org.eclipse.jdt.internal.compiler.impl.ReferenceContext;
+
+public class EclipseShadow extends Shadow {
+ EclipseWorld world;
+ AstNode astNode;
+ //XXXReferenceContext context;
+ AbstractMethodDeclaration enclosingMethod;
+
+ public EclipseShadow(EclipseWorld world, Kind kind, Member signature, AstNode astNode,
+ ReferenceContext context)
+ {
+ super(kind, signature);
+ this.world = world;
+ this.astNode = astNode;
+ //XXX can this fail in practice?
+ this.enclosingMethod = (AbstractMethodDeclaration)context;
+ }
+
+ public World getIWorld() {
+ return world;
+ }
+
+ public boolean hasThis() {
+ return !enclosingMethod.isStatic(); //XXX what about pre-initialization
+ }
+
+ public TypeX getThisType() {
+ return world.fromBinding(enclosingMethod.binding.declaringClass);
+ }
+
+ public TypeX getEnclosingType() {
+ return getThisType(); //??? why is this different from the above
+ }
+
+ public SourceLocation getSourceLocation() {
+ //XXX need to fill this in ASAP
+ return null;
+ }
+
+ public Member getEnclosingCodeSignature() {
+ return world.makeResolvedMember(enclosingMethod.binding);
+ }
+
+ // -- all below here are only used for implementing, not in matching
+ // -- we should probably pull out a super-interface to capture this in type system
+
+ public Var getThisVar() {
+ throw new RuntimeException("unimplemented");
+ }
+
+ public Var getTargetVar() {
+ throw new RuntimeException("unimplemented");
+ }
+
+ public Var getArgVar(int i) {
+ throw new RuntimeException("unimplemented");
+ }
+
+ public Var getThisJoinPointVar() {
+ throw new RuntimeException("unimplemented");
+ }
+
+ public Var getThisJoinPointStaticPartVar() {
+ throw new RuntimeException("unimplemented");
+ }
+
+ public Var getThisEnclosingJoinPointStaticPartVar() {
+ throw new RuntimeException("unimplemented");
+ }
+
+ // --- factory methods
+
+ public static EclipseShadow makeShadow(EclipseWorld world, AstNode astNode,
+ ReferenceContext context)
+ {
+ //XXX make sure we're getting the correct declaring type at call-site
+ if (astNode instanceof AllocationExpression) {
+ AllocationExpression e = (AllocationExpression)astNode;
+ return new EclipseShadow(world, Shadow.ConstructorCall,
+ world.makeResolvedMember(e.binding), astNode, context);
+ } else if (astNode instanceof MessageSend) {
+ MessageSend e = (MessageSend)astNode;
+ return new EclipseShadow(world, Shadow.MethodCall,
+ world.makeResolvedMember(e.binding), astNode, context);
+ } else if (astNode instanceof ExplicitConstructorCall) {
+ //??? these need to be ignored, they don't have shadows
+ return null;
+// ExplicitConstructorCall e = (ExplicitConstructorCall)astNode;
+// return new EclipseShadow(world, Shadow.MethodCall,
+// world.makeResolvedMember(e.binding), astNode, context);
+ } else if (astNode instanceof AbstractMethodDeclaration) {
+ AbstractMethodDeclaration e = (AbstractMethodDeclaration)astNode;
+ Shadow.Kind kind;
+ if (e instanceof AdviceDeclaration) {
+ kind = Shadow.AdviceExecution;
+ } else if (e instanceof MethodDeclaration) {
+ kind = Shadow.MethodExecution;
+ } else if (e instanceof ConstructorDeclaration) {
+ kind = Shadow.ConstructorExecution;
+ } else {
+ throw new RuntimeException("unimplemented: " + e);
+ }
+ return new EclipseShadow(world, kind,
+ world.makeResolvedMember(e.binding), astNode, context);
+ } else {
+ throw new RuntimeException("unimplemented: " + astNode);
+ }
+ }
+
+
+}
diff --git a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/EclipseSourceLocation.java b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/EclipseSourceLocation.java
new file mode 100644
index 000000000..57f96197c
--- /dev/null
+++ b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/EclipseSourceLocation.java
@@ -0,0 +1,65 @@
+/* *******************************************************************
+ * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC).
+ * All rights reserved.
+ * This program and the accompanying materials are made available
+ * under the terms of the Common Public License v1.0
+ * which accompanies this distribution and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * Xerox/PARC initial implementation
+ * ******************************************************************/
+
+
+package org.aspectj.ajdt.internal.compiler.lookup;
+
+import java.io.File;
+
+import org.aspectj.bridge.ISourceLocation;
+import org.eclipse.jdt.internal.compiler.CompilationResult;
+import org.eclipse.jdt.internal.compiler.problem.ProblemHandler;
+
+public class EclipseSourceLocation implements ISourceLocation {
+ CompilationResult result;
+ int startPos, endPos;
+
+ public EclipseSourceLocation(CompilationResult result, int startPos, int endPos) {
+ super();
+ this.result = result;
+ this.startPos = startPos;
+ this.endPos = endPos;
+ }
+
+ public File getSourceFile() {
+ return new File(new String(result.fileName));
+ }
+
+ public int getLine() {
+ return ProblemHandler.searchLineNumber(result.lineSeparatorPositions, startPos);
+ }
+
+ public int getColumn() {
+ return 0; //XXX need better search above to get both
+ }
+
+ public int getEndLine() {
+ return getLine(); //XXX no real need to do better
+ }
+
+
+ /** @return String {file:}line{:column} */
+ public String toString() {
+ StringBuffer sb = new StringBuffer();
+
+ if (getSourceFile() != ISourceLocation.NO_FILE) {
+ sb.append(getSourceFile().getPath());
+ sb.append(":");
+ }
+ sb.append("" + getLine());
+ if (getColumn() != 0) {
+ sb.append(":" + getColumn());
+ }
+ return sb.toString();
+ }
+
+}
diff --git a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/EclipseTypeMunger.java b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/EclipseTypeMunger.java
new file mode 100644
index 000000000..2610a56c0
--- /dev/null
+++ b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/EclipseTypeMunger.java
@@ -0,0 +1,141 @@
+/* *******************************************************************
+ * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC).
+ * All rights reserved.
+ * This program and the accompanying materials are made available
+ * under the terms of the Common Public License v1.0
+ * which accompanies this distribution and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * Xerox/PARC initial implementation
+ * ******************************************************************/
+
+
+package org.aspectj.ajdt.internal.compiler.lookup;
+
+import java.lang.reflect.Modifier;
+
+import org.aspectj.bridge.*;
+import org.aspectj.bridge.ISourceLocation;
+import org.aspectj.weaver.*;
+import org.aspectj.weaver.ConcreteTypeMunger;
+import org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration;
+import org.eclipse.jdt.internal.compiler.lookup.*;
+import org.eclipse.jdt.internal.compiler.lookup.ClassScope;
+
+
+public class EclipseTypeMunger extends ConcreteTypeMunger {
+ protected ReferenceBinding targetBinding = null;
+ private AbstractMethodDeclaration sourceMethod;
+
+ public EclipseTypeMunger(ResolvedTypeMunger munger, ResolvedTypeX aspectType,
+ AbstractMethodDeclaration sourceMethod)
+ {
+ super(munger, aspectType);
+ this.sourceMethod = sourceMethod;
+ }
+
+ public String toString() {
+ return "(EclipseTypeMunger " + getMunger() + ")";
+ }
+
+ private boolean match(ClassScope scope) {
+ if (targetBinding == null) {
+ TypeX targetTypeX = munger.getSignature().getDeclaringType();
+ targetBinding =
+ (ReferenceBinding)EclipseWorld.fromScopeLookupEnvironment(scope).makeTypeBinding(targetTypeX);
+ }
+ //??? assumes instance uniqueness for ReferenceBindings
+ return targetBinding == scope.referenceContext.binding;
+
+ }
+
+ /**
+ * Modifies signatures of a TypeBinding through its ClassScope,
+ * i.e. adds Method|FieldBindings, plays with inheritance, ...
+ */
+ public boolean munge(ClassScope classScope) {
+ if (!match(classScope)) return false;
+
+ if (munger.getKind() == ResolvedTypeMunger.Field) {
+ mungeNewField(classScope, (NewFieldTypeMunger)munger);
+ } else if (munger.getKind() == ResolvedTypeMunger.Method) {
+ mungeNewMethod(classScope, (NewMethodTypeMunger)munger);
+ } else if (munger.getKind() == ResolvedTypeMunger.Constructor) {
+ mungeNewConstructor(classScope, (NewConstructorTypeMunger)munger);
+ } else {
+ throw new RuntimeException("unimplemented");
+ }
+ return true;
+ }
+
+
+ private void mungeNewMethod(ClassScope classScope, NewMethodTypeMunger munger) {
+ EclipseWorld world = EclipseWorld.fromScopeLookupEnvironment(classScope);
+
+// if (shouldTreatAsPublic()) {
+// MethodBinding binding = world.makeMethodBinding(munger.getSignature());
+// findOrCreateInterTypeMemberFinder(classScope).addInterTypeMethod(binding);
+// //classScope.referenceContext.binding.addMethod(binding);
+// } else {
+ InterTypeMethodBinding binding =
+ new InterTypeMethodBinding(world, munger.getSignature(), aspectType, sourceMethod);
+ findOrCreateInterTypeMemberFinder(classScope).addInterTypeMethod(binding);
+// }
+
+ }
+ private void mungeNewConstructor(ClassScope classScope, NewConstructorTypeMunger munger) {
+ EclipseWorld world = EclipseWorld.fromScopeLookupEnvironment(classScope);
+
+ if (shouldTreatAsPublic()) {
+ MethodBinding binding = world.makeMethodBinding(munger.getSignature());
+ findOrCreateInterTypeMemberFinder(classScope).addInterTypeMethod(binding);
+ //classScope.referenceContext.binding.addMethod(binding);
+ } else {
+ InterTypeMethodBinding binding =
+ new InterTypeMethodBinding(world, munger.getSignature(), aspectType, sourceMethod);
+ findOrCreateInterTypeMemberFinder(classScope).addInterTypeMethod(binding);
+ }
+
+ }
+
+ private void mungeNewField(ClassScope classScope, NewFieldTypeMunger munger) {
+ EclipseWorld world = EclipseWorld.fromScopeLookupEnvironment(classScope);
+
+ if (shouldTreatAsPublic() && !targetBinding.isInterface()) {
+ FieldBinding binding = world.makeFieldBinding(munger.getSignature());
+ findOrCreateInterTypeMemberFinder(classScope).addInterTypeField(binding);
+ //classScope.referenceContext.binding.addField(binding);
+ } else {
+ InterTypeFieldBinding binding =
+ new InterTypeFieldBinding(world, munger.getSignature(), aspectType, sourceMethod);
+ findOrCreateInterTypeMemberFinder(classScope).addInterTypeField(binding);
+ }
+ }
+
+
+ private boolean shouldTreatAsPublic() {
+ //??? this is where we could fairly easily choose to treat package-protected
+ //??? introductions like public ones when the target type and the aspect
+ //??? are in the same package
+ return Modifier.isPublic(munger.getSignature().getModifiers());
+ }
+
+
+ private InterTypeMemberFinder findOrCreateInterTypeMemberFinder(ClassScope classScope) {
+ InterTypeMemberFinder finder =
+ (InterTypeMemberFinder)classScope.referenceContext.binding.memberFinder;
+ if (finder == null) {
+ finder = new InterTypeMemberFinder();
+ classScope.referenceContext.binding.memberFinder = finder;
+ finder.sourceTypeBinding = classScope.referenceContext.binding;
+ }
+ return finder;
+ }
+
+ public ISourceLocation getSourceLocation() {
+ return new EclipseSourceLocation(sourceMethod.compilationResult,
+ sourceMethod.sourceStart, sourceMethod.sourceEnd);
+ }
+
+}
diff --git a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/EclipseWorld.java b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/EclipseWorld.java
new file mode 100644
index 000000000..f7e74ddc2
--- /dev/null
+++ b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/EclipseWorld.java
@@ -0,0 +1,263 @@
+/* *******************************************************************
+ * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC).
+ * All rights reserved.
+ * This program and the accompanying materials are made available
+ * under the terms of the Common Public License v1.0
+ * which accompanies this distribution and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * Xerox/PARC initial implementation
+ * ******************************************************************/
+
+
+package org.aspectj.ajdt.internal.compiler.lookup;
+
+import java.util.*;
+
+import org.aspectj.ajdt.internal.compiler.ast.AstUtil;
+import org.aspectj.ajdt.internal.core.builder.*;
+import org.aspectj.ajdt.internal.core.builder.AjBuildManager;
+import org.aspectj.bridge.IMessageHandler;
+import org.aspectj.weaver.*;
+import org.aspectj.weaver.patterns.*;
+import org.eclipse.jdt.internal.compiler.ast.*;
+import org.eclipse.jdt.internal.compiler.impl.*;
+import org.eclipse.jdt.internal.compiler.impl.Constant;
+import org.eclipse.jdt.internal.compiler.lookup.*;
+import org.eclipse.jdt.internal.compiler.util.CharOperation;
+
+public class EclipseWorld extends World {
+ public static boolean DEBUG = false;
+
+ public AjBuildManager buildManager;
+ private LookupEnvironment lookupEnvironment;
+
+ private Map addedTypeBindings = new HashMap();
+
+ public static EclipseWorld forLookupEnvironment(LookupEnvironment env) {
+ AjLookupEnvironment aenv = (AjLookupEnvironment)env;
+ return aenv.world;
+ }
+
+ public static EclipseWorld fromScopeLookupEnvironment(Scope scope) {
+ return forLookupEnvironment(AstUtil.getCompilationUnitScope(scope).environment);
+ }
+
+
+ public EclipseWorld(LookupEnvironment lookupEnvironment, IMessageHandler handler) {
+ this.lookupEnvironment = lookupEnvironment;
+ setMessageHandler(handler);
+ }
+
+ public Advice concreteAdvice(AdviceKind kind, Pointcut p, Member m, int extraMods,
+ int start, int end, ISourceContext context)
+ {
+ return new EclipseAdvice(kind, p, m, extraMods, start, end, context);
+ }
+
+ public ConcreteTypeMunger concreteTypeMunger(
+ ResolvedTypeMunger munger, ResolvedTypeX aspectType)
+ {
+ return null;
+ //throw new RuntimeException("unimplemented");
+ }
+
+ protected ResolvedTypeX resolveObjectType(TypeX ty) {
+ String n = ty.getName();
+ //n = n.replace('$', '.');
+ char[][] name = CharOperation.splitOn('.', n.toCharArray()); //ty.getName().toCharArray());
+ ReferenceBinding ret = lookupEnvironment.getType(name);
+ //System.out.println("name: " + ty.getName() + ", " + ret);
+ if (ret == null || ret instanceof ProblemReferenceBinding) return ResolvedTypeX.MISSING;
+ return new EclipseObjectType(ty.getSignature(), this, ret);
+ }
+
+
+ public ResolvedTypeX fromEclipse(ReferenceBinding binding) {
+ if (binding == null) return ResolvedTypeX.MISSING;
+ //??? this seems terribly inefficient
+ //System.out.println("resolving: " + binding + ", name = " + getName(binding));
+ ResolvedTypeX ret = resolve(fromBinding(binding));
+ //System.out.println(" got: " + ret);
+ return ret;
+ }
+
+ public ResolvedTypeX[] fromEclipse(ReferenceBinding[] bindings) {
+ if (bindings == null) {
+ return ResolvedTypeX.NONE;
+ }
+ int len = bindings.length;
+ ResolvedTypeX[] ret = new ResolvedTypeX[len];
+ for (int i=0; i < len; i++) {
+ ret[i] = fromEclipse(bindings[i]);
+ }
+ return ret;
+ }
+
+
+ private static String getName(TypeBinding binding) {
+ String packageName = new String(binding.qualifiedPackageName());
+ String className = new String(binding.qualifiedSourceName()).replace('.', '$');
+ if (packageName.length() > 0) {
+ className = packageName + "." + className;
+ }
+ //XXX doesn't handle arrays correctly (or primitives?)
+ return new String(className);
+ }
+
+
+
+ //??? going back and forth between strings and bindings is a waste of cycles
+ public static TypeX fromBinding(TypeBinding binding) {
+// if (binding instanceof ReferenceBinding) {
+// return fromEclipse( (ReferenceBinding)binding);
+// } else {
+
+ if (binding instanceof HelperInterfaceBinding) {
+ return ((HelperInterfaceBinding)binding).getTypeX();
+ }
+ if (binding.qualifiedSourceName() == null) return ResolvedTypeX.MISSING;
+ return TypeX.forName(getName(binding));
+// }
+ }
+
+ public static TypeX[] fromBindings(TypeBinding[] bindings) {
+ int len = bindings.length;
+ TypeX[] ret = new TypeX[len];
+ for (int i=0; i<len; i++) {
+ ret[i] = fromBinding(bindings[i]);
+ }
+ return ret;
+ }
+
+ public static AstNode astForLocation(IHasPosition location) {
+ return new EmptyStatement(location.getStart(), location.getEnd());
+ }
+
+ public Collection getTypeMungers() {
+ return crosscuttingMembersSet.getTypeMungers();
+ }
+
+ public static ResolvedMember makeResolvedMember(MethodBinding binding) {
+ return new ResolvedMember(
+ Member.METHOD,
+ fromBinding(binding.declaringClass),
+ binding.modifiers,
+ fromBinding(binding.returnType),
+ new String(binding.selector),
+ fromBindings(binding.parameters));
+ //XXX need to add checked exceptions
+ }
+
+ public static ResolvedMember makeResolvedMember(FieldBinding binding) {
+ return new ResolvedMember(
+ Member.FIELD,
+ fromBinding(binding.declaringClass),
+ binding.modifiers,
+ fromBinding(binding.type),
+ new String(binding.name),
+ TypeX.NONE);
+ }
+
+ public TypeBinding makeTypeBinding(TypeX typeX) {
+ //System.out.println("in: " + typeX.getSignature() + " have: " + addedTypeBindings);
+ TypeBinding ret = (TypeBinding)addedTypeBindings.get(typeX);
+ if (ret != null) return ret;
+
+ if (typeX.isPrimitive()) {
+ if (typeX == ResolvedTypeX.BOOLEAN) return BaseTypes.BooleanBinding;
+ if (typeX == ResolvedTypeX.BYTE) return BaseTypes.ByteBinding;
+ if (typeX == ResolvedTypeX.CHAR) return BaseTypes.CharBinding;
+ if (typeX == ResolvedTypeX.DOUBLE) return BaseTypes.DoubleBinding;
+ if (typeX == ResolvedTypeX.FLOAT) return BaseTypes.FloatBinding;
+ if (typeX == ResolvedTypeX.INT) return BaseTypes.IntBinding;
+ if (typeX == ResolvedTypeX.LONG) return BaseTypes.LongBinding;
+ if (typeX == ResolvedTypeX.SHORT) return BaseTypes.ShortBinding;
+ if (typeX == ResolvedTypeX.VOID) return BaseTypes.VoidBinding;
+ throw new RuntimeException("weird primitive type " + typeX);
+ } else if (typeX.isArray()) {
+ int dim = 0;
+ while (typeX.isArray()) {
+ dim++;
+ typeX = typeX.getComponentType();
+ }
+ return new ArrayBinding(makeTypeBinding(typeX), dim);
+ } else {
+ ResolvedTypeX rt = typeX.resolve(this);
+ //System.out.println("typex: " + typeX + ", " + rt);
+ if (rt == ResolvedTypeX.MISSING) {
+ throw new RuntimeException("shouldn't be missing: " + typeX);
+ }
+ return ((EclipseObjectType)rt).getBinding();
+ }
+ }
+
+ public TypeBinding[] makeTypeBindings(TypeX[] types) {
+ int len = types.length;
+ TypeBinding[] ret = new TypeBinding[len];
+
+ for (int i = 0; i < len; i++) {
+ ret[i] = makeTypeBinding(types[i]);
+ }
+ return ret;
+ }
+
+
+ public FieldBinding makeFieldBinding(ResolvedMember member) {
+ return new FieldBinding(member.getName().toCharArray(),
+ makeTypeBinding(member.getReturnType()),
+ member.getModifiers(),
+ (ReferenceBinding)makeTypeBinding(member.getDeclaringType()),
+ Constant.NotAConstant);
+ }
+
+
+ public MethodBinding makeMethodBinding(ResolvedMember member) {
+ if (member.getExceptions() != null && member.getExceptions().length > 0) {
+ throw new RuntimeException("unimplemented");
+ }
+ return new MethodBinding(member.getModifiers(),
+ member.getName().toCharArray(),
+ makeTypeBinding(member.getReturnType()),
+ makeTypeBindings(member.getParameterTypes()),
+ new ReferenceBinding[0],
+ (ReferenceBinding)makeTypeBinding(member.getDeclaringType()));
+ }
+
+ public MethodBinding makeMethodBindingForCall(Member member) {
+ return new MethodBinding(member.getCallsiteModifiers(),
+ member.getName().toCharArray(),
+ makeTypeBinding(member.getReturnType()),
+ makeTypeBindings(member.getParameterTypes()),
+ new ReferenceBinding[0],
+ (ReferenceBinding)makeTypeBinding(member.getDeclaringType()));
+ }
+
+ public void finishedCompilationUnit(CompilationUnitDeclaration unit) {
+ if (buildManager.doGenerateModel()) {
+ AsmBuilder.build(unit, buildManager.getStructureModel());
+ }
+ }
+
+
+ public void addTypeBinding(TypeBinding binding) {
+ addedTypeBindings.put(fromBinding(binding), binding);
+ }
+
+ public Shadow makeShadow(
+ AstNode location,
+ ReferenceContext context)
+ {
+ return EclipseShadow.makeShadow(this, location, context);
+ }
+
+ public Shadow makeShadow(
+ ReferenceContext context)
+ {
+ return EclipseShadow.makeShadow(this, (AstNode)context, context);
+ }
+
+
+
+}
diff --git a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/HelperInterfaceBinding.java b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/HelperInterfaceBinding.java
new file mode 100644
index 000000000..132a9b294
--- /dev/null
+++ b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/HelperInterfaceBinding.java
@@ -0,0 +1,99 @@
+/* *******************************************************************
+ * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC).
+ * All rights reserved.
+ * This program and the accompanying materials are made available
+ * under the terms of the Common Public License v1.0
+ * which accompanies this distribution and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * Xerox/PARC initial implementation
+ * ******************************************************************/
+
+
+ package org.aspectj.ajdt.internal.compiler.lookup;
+
+import java.util.*;
+
+import org.aspectj.weaver.*;
+import org.aspectj.weaver.TypeX;
+import org.eclipse.jdt.internal.compiler.*;
+import org.eclipse.jdt.internal.compiler.lookup.*;
+
+public class HelperInterfaceBinding extends SourceTypeBinding {
+ private TypeX typeX;
+ SourceTypeBinding enclosingType;
+ List methods = new ArrayList();
+
+ public HelperInterfaceBinding(SourceTypeBinding enclosingType, TypeX typeX) {
+ super();
+ this.fPackage = enclosingType.fPackage;
+ //this.fileName = scope.referenceCompilationUnit().getFileName();
+ this.modifiers = AccPublic | AccInterface;
+ this.sourceName = enclosingType.scope.referenceContext.name;
+ this.enclosingType = enclosingType;
+ this.typeX = typeX;
+
+ this.scope = enclosingType.scope;
+ }
+
+ public HelperInterfaceBinding(
+ char[][] compoundName,
+ PackageBinding fPackage,
+ ClassScope scope) {
+ super(compoundName, fPackage, scope);
+ }
+
+ public char[] getFileName() {
+ return enclosingType.getFileName();
+ }
+
+ public TypeX getTypeX() {
+ return typeX;
+ }
+
+ public void addMethod(EclipseWorld world , ResolvedMember member) {
+ MethodBinding binding = world.makeMethodBinding(member);
+ this.methods.add(binding);
+ }
+
+ public FieldBinding[] fields() { return new FieldBinding[0]; }
+
+ public MethodBinding[] methods() { return new MethodBinding[0]; }
+
+
+ public char[] constantPoolName() {
+ String sig = typeX.getSignature();
+ return sig.substring(1, sig.length()-1).toCharArray();
+ }
+
+ public void generateClass(CompilationResult result, ClassFile enclosingClassFile) {
+ ClassFile classFile = new ClassFile(this, enclosingClassFile, false);
+ classFile.addFieldInfos();
+
+ classFile.setForMethodInfos();
+ for (Iterator i = methods.iterator(); i.hasNext(); ) {
+ MethodBinding b = (MethodBinding)i.next();
+ generateMethod(classFile, b);
+ }
+
+ classFile.addAttributes();
+
+ result.record(this.constantPoolName(), classFile);
+ }
+
+
+ private void generateMethod(ClassFile classFile, MethodBinding binding) {
+ classFile.generateMethodInfoHeader(binding);
+ int methodAttributeOffset = classFile.contentsOffset;
+ int attributeNumber = classFile.generateMethodInfoAttribute(binding);
+ classFile.completeMethodInfo(methodAttributeOffset, attributeNumber);
+ }
+
+
+
+ public ReferenceBinding[] superInterfaces() {
+ return new ReferenceBinding[0];
+ }
+
+}
diff --git a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/InterTypeFieldBinding.java b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/InterTypeFieldBinding.java
new file mode 100644
index 000000000..db30f03ff
--- /dev/null
+++ b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/InterTypeFieldBinding.java
@@ -0,0 +1,113 @@
+/* *******************************************************************
+ * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC).
+ * All rights reserved.
+ * This program and the accompanying materials are made available
+ * under the terms of the Common Public License v1.0
+ * which accompanies this distribution and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * Xerox/PARC initial implementation
+ * ******************************************************************/
+
+
+package org.aspectj.ajdt.internal.compiler.lookup;
+
+import java.lang.reflect.Modifier;
+
+import org.aspectj.ajdt.internal.compiler.ast.AstUtil;
+import org.aspectj.weaver.*;
+import org.aspectj.weaver.NameMangler;
+import org.eclipse.jdt.internal.compiler.ast.*;
+import org.eclipse.jdt.internal.compiler.ast.FieldDeclaration;
+import org.eclipse.jdt.internal.compiler.impl.Constant;
+import org.eclipse.jdt.internal.compiler.lookup.*;
+import org.eclipse.jdt.internal.compiler.util.CharOperation;
+
+public class InterTypeFieldBinding extends FieldBinding {
+ public ReferenceBinding targetType;
+ public SyntheticAccessMethodBinding reader;
+ public SyntheticAccessMethodBinding writer;
+ public AbstractMethodDeclaration sourceMethod;
+
+ public InterTypeFieldBinding(EclipseWorld world, ResolvedMember signature, TypeX withinType,
+ AbstractMethodDeclaration sourceMethod)
+ {
+ super(world.makeFieldBinding(signature), null);
+ this.sourceMethod = sourceMethod;
+
+ targetType = (ReferenceBinding)world.makeTypeBinding(signature.getDeclaringType());
+ this.declaringClass = (ReferenceBinding)world.makeTypeBinding(withinType);
+
+ reader = new SimpleSyntheticAccessMethodBinding(world.makeMethodBinding(
+ AjcMemberMaker.interFieldGetDispatcher(signature, withinType)
+ ));
+
+ writer = new SimpleSyntheticAccessMethodBinding(world.makeMethodBinding(
+ AjcMemberMaker.interFieldSetDispatcher(signature, withinType)
+ ));
+ }
+
+ public boolean canBeSeenBy(TypeBinding receiverType, InvocationSite invocationSite, Scope scope) {
+ if (isPublic()) return true;
+
+ SourceTypeBinding invocationType = scope.invocationType();
+ //System.out.println("receiver: " + receiverType + ", " + invocationType);
+
+ if (invocationType == declaringClass) return true;
+
+
+ // if (invocationType.isPrivileged) {
+ // System.out.println("privileged access to: " + this);
+ // return true;
+ // }
+
+ if (isProtected()) {
+ throw new RuntimeException("unimplemented");
+ }
+
+ //XXX make sure this walks correctly
+ if (isPrivate()) {
+ // answer true if the receiverType is the declaringClass
+ // AND the invocationType and the declaringClass have a common enclosingType
+ if (receiverType != declaringClass) return false;
+
+ if (invocationType != declaringClass) {
+ ReferenceBinding outerInvocationType = invocationType;
+ ReferenceBinding temp = outerInvocationType.enclosingType();
+ while (temp != null) {
+ outerInvocationType = temp;
+ temp = temp.enclosingType();
+ }
+
+ ReferenceBinding outerDeclaringClass = declaringClass;
+ temp = outerDeclaringClass.enclosingType();
+ while (temp != null) {
+ outerDeclaringClass = temp;
+ temp = temp.enclosingType();
+ }
+ if (outerInvocationType != outerDeclaringClass) return false;
+ }
+ return true;
+ }
+
+ // isDefault()
+ if (invocationType.fPackage == declaringClass.fPackage) return true;
+ return false;
+ }
+
+
+ public SyntheticAccessMethodBinding getAccessMethod(boolean isReadAccess) {
+ if (isReadAccess) return reader;
+ else return writer;
+ }
+
+ public boolean alwaysNeedsAccessMethod(boolean isReadAccess) { return true; }
+
+
+
+ public ReferenceBinding getTargetType() {
+ return targetType;
+ }
+
+}
diff --git a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/InterTypeMemberFinder.java b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/InterTypeMemberFinder.java
new file mode 100644
index 000000000..acc5cb9cf
--- /dev/null
+++ b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/InterTypeMemberFinder.java
@@ -0,0 +1,401 @@
+/* *******************************************************************
+ * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC).
+ * All rights reserved.
+ * This program and the accompanying materials are made available
+ * under the terms of the Common Public License v1.0
+ * which accompanies this distribution and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * Xerox/PARC initial implementation
+ * ******************************************************************/
+
+
+package org.aspectj.ajdt.internal.compiler.lookup;
+
+import java.util.*;
+
+import org.aspectj.weaver.*;
+import org.aspectj.weaver.ResolvedTypeX;
+import org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration;
+import org.eclipse.jdt.internal.compiler.lookup.*;
+import org.eclipse.jdt.internal.compiler.problem.ProblemReporter;
+import org.eclipse.jdt.internal.compiler.util.CharOperation;
+
+public class InterTypeMemberFinder implements IMemberFinder {
+ private List interTypeFields = new ArrayList();
+ private List interTypeMethods = new ArrayList();
+
+ public SourceTypeBinding sourceTypeBinding;
+
+ public FieldBinding getField(
+ SourceTypeBinding sourceTypeBinding,
+ char[] fieldName,
+ InvocationSite site,
+ Scope scope)
+ {
+ FieldBinding retField = sourceTypeBinding.getFieldBase(fieldName);
+ if (interTypeFields.isEmpty()) return retField;
+ int fieldLength = fieldName.length;
+
+ for (int i=0, len=interTypeFields.size(); i < len; i++) {
+ FieldBinding field = (FieldBinding)interTypeFields.get(i);
+ if (field.name.length == fieldLength && CharOperation.prefixEquals(field.name, fieldName)) {
+ retField = resolveConflicts(sourceTypeBinding, retField, field, site, scope);
+ }
+ }
+
+ return retField;
+ }
+
+ private FieldBinding resolveConflicts(
+ SourceTypeBinding sourceTypeBinding,
+ FieldBinding retField,
+ FieldBinding field,
+ InvocationSite site,
+ Scope scope)
+ {
+ if (retField == null) return field;
+ if (!field.canBeSeenBy(sourceTypeBinding, site, scope)) return retField;
+ if (!retField.canBeSeenBy(sourceTypeBinding, site, scope)) return field;
+ //XXX need dominates check on aspects
+ return new ProblemFieldBinding(retField.declaringClass, retField.name, ProblemReporter.Ambiguous);
+ }
+
+
+// private void reportConflicts(SourceTypeBinding sourceTypeBinding,
+// MethodBinding m1, MethodBinding m2)
+// {
+// if (m1 == m2) {
+// System.err.println("odd that we're ecomparing the same: " + m1);
+// return;
+// }
+//
+// if (!m1.areParametersEqual(m2)) return;
+
+// if (m1 instanceof InterTypeMethodBinding) {
+// if (m2 instanceof InterTypeMethodBinding) {
+// reportConflictsBoth(sourceTypeBinding,
+// (InterTypeMethodBinding)m1,
+// (InterTypeMethodBinding)m2);
+// } else {
+// reportConflictsOne(sourceTypeBinding,
+// (InterTypeMethodBinding)m1,
+// m2);
+// }
+// } else if (m2 instanceof InterTypeMethodBinding) {
+// reportConflictsOne(sourceTypeBinding,
+// (InterTypeMethodBinding)m2,
+// m1);
+// } else {
+// reportConflictsNone(sourceTypeBinding,
+// m2,
+// m1);
+// }
+// }
+
+
+// private void reportConflicts(
+// SourceTypeBinding sourceTypeBinding,
+// MethodBinding m1,
+// MethodBinding m2)
+// {
+// //System.err.println("compare: " + m1 + " with " + m2);
+//
+// if (m1 == m2) {
+// System.err.println("odd that we're ecomparing the same: " + m1);
+// return;
+// }
+//
+// if (!m1.areParametersEqual(m2)) return;
+//
+// //System.err.println("t1: " + getTargetType(m1) + ", " + getTargetType(m2));
+//
+// if (getTargetType(m1) != getTargetType(m2)) return;
+//
+// if (m1.declaringClass == m2.declaringClass) {
+// duplicateMethodBinding(m1, m2);
+// return;
+// }
+//
+//
+// if (m1.isPublic() || m2.isPublic()) {
+// duplicateMethodBinding(m1, m2);
+// return;
+// }
+//
+// // handle the wierd case where the aspect is a subtype of the target
+// if (m2.isProtected()) {
+// if (m2.declaringClass.isSuperclassOf(m1.declaringClass)) {
+// duplicateMethodBinding(m1, m2);
+// }
+// // don't return because we also want to do the package test
+// }
+//
+// if (!m1.isPrivate() || !m2.isPrivate()) {
+// // at least package visible
+// if (m1.declaringClass.getPackage() == m2.declaringClass.getPackage()) {
+// duplicateMethodBinding(m1, m2);
+// }
+// return;
+// }
+//
+// //XXX think about inner types some day
+// }
+////
+ private boolean isVisible(MethodBinding m1, ReferenceBinding s) {
+ if (m1.declaringClass == s) return true;
+
+
+ if (m1.isPublic()) return true;
+
+ //don't need to handle protected
+ //if (m1.isProtected()) {
+
+
+ if (!m1.isPrivate()) {
+ // at least package visible
+ return (m1.declaringClass.getPackage() == s.getPackage());
+ }
+
+ return false;
+ }
+
+//
+// private void duplicateMethodBinding(MethodBinding m1, MethodBinding m2) {
+// ReferenceBinding t1 = m1.declaringClass;
+// ReferenceBinding t2 = m2.declaringClass;
+//
+//
+//
+//
+//
+//
+// if (!(t1 instanceof SourceTypeBinding) || !(t2 instanceof SourceTypeBinding)) {
+// throw new RuntimeException("unimplemented");
+// }
+//
+// SourceTypeBinding s1 = (SourceTypeBinding)t1;
+// SourceTypeBinding s2 = (SourceTypeBinding)t2;
+//
+// if (m1.sourceMethod() != null) {
+// s1.scope.problemReporter().duplicateMethodInType(s2, m1.sourceMethod());
+// }
+// if (m2.sourceMethod() != null) {
+// s2.scope.problemReporter().duplicateMethodInType(s1, m2.sourceMethod());
+// }
+// }
+
+// private void reportConflictsNone(
+// SourceTypeBinding sourceTypeBinding,
+// MethodBinding m2,
+// MethodBinding m1)
+// {
+// throw new RuntimeException("not possible");
+// }
+
+
+
+// ReferenceBinding t1 = getDeclaringClass(m1);
+// //.declaringClass;
+// ReferenceBinding t2 = getDeclaringClass(m2);
+// //.declaringClass;
+//
+// if (t1 == t2) {
+// AbstractMethodDeclaration methodDecl = m2.sourceMethod(); // cannot be retrieved after binding is lost
+// System.err.println("duplicate: " + t1 + ", " + t2);
+// sourceTypeBinding.scope.problemReporter().duplicateMethodInType(sourceTypeBinding, methodDecl);
+// methodDecl.binding = null;
+// //methods[m] = null; //XXX duplicate problem reports
+// return;
+// }
+//
+// if (!(t1 instanceof SourceTypeBinding) || !(t2 instanceof SourceTypeBinding)) {
+// throw new RuntimeException("unimplemented");
+// }
+//
+// SourceTypeBinding s1 = (SourceTypeBinding)t1;
+// SourceTypeBinding s2 = (SourceTypeBinding)t2;
+//
+//
+// if (m1.canBeSeenBy(s1, null, s2.scope) || m2.canBeSeenBy(s2, null, s1.scope)) {
+// s1.scope.problemReporter().duplicateMethodInType(s2, m1.sourceMethod());
+// s2.scope.problemReporter().duplicateMethodInType(s1, m2.sourceMethod());
+// }
+// }
+
+ private ReferenceBinding getTargetType(MethodBinding m2) {
+ if (m2 instanceof InterTypeMethodBinding) {
+ return ((InterTypeMethodBinding)m2).getTargetType();
+ }
+
+ return m2.declaringClass;
+ }
+
+
+
+ //XXX conflicts
+ public MethodBinding[] getMethods(
+ SourceTypeBinding sourceTypeBinding,
+ char[] selector) {
+// System.err.println("getMethods: " + new String(sourceTypeBinding.signature()) +
+// ", " + new String(selector));
+
+ MethodBinding[] orig = sourceTypeBinding.getMethodsBase(selector);
+ if (interTypeMethods.isEmpty()) return orig;
+
+ List ret = new ArrayList(Arrays.asList(orig));
+// System.err.println("declared method: " + ret + " inters = " + interTypeMethods);
+
+ for (int i=0, len=interTypeMethods.size(); i < len; i++) {
+ MethodBinding method = (MethodBinding)interTypeMethods.get(i);
+
+ if (CharOperation.equals(selector, method.selector)) {
+ ret.add(method);
+ }
+ }
+
+ if (ret.isEmpty()) return SourceTypeBinding.NoMethods;
+
+// System.err.println("method: " + ret);
+
+ // check for conflicts
+// int len = ret.size();
+// if (len > 1) {
+// for (int i=0; i <len; i++) {
+// MethodBinding m1 = (MethodBinding)ret.get(i);
+// for (int j=i+1; j < len; j++) {
+// MethodBinding m2 = (MethodBinding)ret.get(j);
+// //reportConflicts(sourceTypeBinding, m1, m2);
+// }
+// }
+// }
+
+
+ //System.err.println("got methods: " + ret + " on " + sourceTypeBinding);
+
+ return (MethodBinding[])ret.toArray(new MethodBinding[ret.size()]);
+ }
+
+ public MethodBinding getExactMethod(
+ SourceTypeBinding sourceTypeBinding,
+ char[] selector,
+ TypeBinding[] argumentTypes)
+ {
+ MethodBinding ret = sourceTypeBinding.getExactMethodBase(selector, argumentTypes);
+ if (ret != null) return ret;
+
+ for (int i=0, len=interTypeMethods.size(); i < len; i++) {
+ MethodBinding im =
+ (MethodBinding)interTypeMethods.get(i);
+ if (matches(im, selector, argumentTypes)) {
+ return im;
+ }
+ }
+ return null;
+ }
+// if (isVisible(im, sourceTypeBinding)) {
+// if (ret == null) {
+// ret = im;
+// } else {
+// ret = resolveOverride(ret, im);
+// }
+// }
+// }
+// }
+// return ret;
+// }
+
+// private MethodBinding resolveOverride(MethodBinding m1, MethodBinding m2) {
+// ReferenceBinding t1 = getTargetType(m1);
+// ReferenceBinding t2 = getTargetType(m2);
+// if (t1 == t2) {
+// //XXX also need a test for completely matching sigs
+// if (m1.isAbstract()) return m2;
+// else if (m2.isAbstract()) return m1;
+//
+//
+// if (m1 instanceof InterTypeMethodBinding) {
+// //XXX need to handle dominates here
+// EclipseWorld world = EclipseWorld.fromScopeLookupEnvironment(sourceTypeBinding.scope);
+// int cmp = compareAspectPrecedence(world.fromEclipse(m1.declaringClass),
+// world.fromEclipse(m2.declaringClass));
+// if (cmp < 0) return m2;
+// else if (cmp > 0) return m1;
+// }
+//
+// duplicateMethodBinding(m1, m2);
+// return null;
+// }
+// if (t1.isSuperclassOf(t2)) {
+// return m2;
+// }
+// if (t2.isSuperclassOf(t1)) {
+// return m1;
+// }
+//
+// duplicateMethodBinding(m1, m2);
+// return null;
+// }
+
+
+// private int compareAspectPrecedence(ResolvedTypeX a1, ResolvedTypeX a2) {
+// World world = a1.getWorld();
+// int ret = world.compareByDominates(a1, a2);
+// if (ret == 0) {
+// if (a1.isAssignableFrom(a2)) return -1;
+// if (a2.isAssignableFrom(a1)) return +1;
+// }
+// return ret;
+// }
+
+
+ //
+ private boolean matches(MethodBinding m1, MethodBinding m2) {
+ return matches(m1, m2.selector, m2.parameters);
+ // &&
+ // (isVisible(m1, m2.declaringClass) || isVisible(m2, m1.declaringClass));
+ }
+
+ private boolean matches(MethodBinding method, char[] selector, TypeBinding[] argumentTypes) {
+ if (!CharOperation.equals(selector, method.selector)) return false;
+ int argCount = argumentTypes.length;
+ if (method.parameters.length != argCount) return false;
+
+ TypeBinding[] toMatch = method.parameters;
+ for (int p = 0; p < argCount; p++) {
+ if (toMatch[p] != argumentTypes[p]) return false;
+ }
+ return true;
+ }
+
+
+
+
+ public void addInterTypeField(FieldBinding binding) {
+ interTypeFields.add(binding);
+ }
+
+ public void addInterTypeMethod(MethodBinding binding) {
+ // check for conflicts with existing methods, should really check type as well...
+ //System.err.println("adding: " + binding + " to " + sourceTypeBinding);
+ if (isVisible(binding, sourceTypeBinding)) {
+ MethodBinding[] baseMethods = sourceTypeBinding.methods;
+ for (int i=0, len=baseMethods.length; i < len; i++) {
+ MethodBinding b = baseMethods[i];
+ if (matches(binding, b)) {
+ // this always means we should remove the existing method
+ if (b.sourceMethod() != null) {
+ b.sourceMethod().binding = null;
+ }
+ sourceTypeBinding.removeMethod(i);
+ //System.err.println(" left: " + Arrays.asList(sourceTypeBinding.methods));
+ break;
+ }
+ }
+ }
+
+ interTypeMethods.add(binding);
+ }
+
+}
diff --git a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/InterTypeMethodBinding.java b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/InterTypeMethodBinding.java
new file mode 100644
index 000000000..1a0d8066c
--- /dev/null
+++ b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/InterTypeMethodBinding.java
@@ -0,0 +1,147 @@
+/* *******************************************************************
+ * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC).
+ * All rights reserved.
+ * This program and the accompanying materials are made available
+ * under the terms of the Common Public License v1.0
+ * which accompanies this distribution and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * Xerox/PARC initial implementation
+ * ******************************************************************/
+
+
+package org.aspectj.ajdt.internal.compiler.lookup;
+
+import org.aspectj.weaver.*;
+import org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration;
+import org.eclipse.jdt.internal.compiler.lookup.*;
+
+public class InterTypeMethodBinding extends MethodBinding {
+ //private ReferenceBinding withinType;
+ private ReferenceBinding targetType;
+ private MethodBinding syntheticMethod;
+
+ //public MethodBinding introducedMethod;
+
+ public AbstractMethodDeclaration sourceMethod;
+
+ public InterTypeMethodBinding(EclipseWorld world, ResolvedMember signature, TypeX withinType,
+ AbstractMethodDeclaration sourceMethod)
+ {
+ super(world.makeMethodBinding(signature), null);
+ this.sourceMethod = sourceMethod;
+
+ targetType = (ReferenceBinding)world.makeTypeBinding(signature.getDeclaringType());
+ this.declaringClass = (ReferenceBinding)world.makeTypeBinding(withinType);
+
+ if (signature.getKind() == Member.METHOD) {
+ syntheticMethod =
+ world.makeMethodBinding(AjcMemberMaker.interMethodDispatcher(signature, withinType));
+ } else {
+ syntheticMethod = world.makeMethodBinding(
+ AjcMemberMaker.interConstructor(world.resolve(signature.getDeclaringType()),
+ signature, withinType));
+ }
+
+
+ }
+
+//
+// this.declaringClass =
+//
+//
+//
+// char[] dispatch2Name;
+// if (Modifier.isPublic(modifiers)) {
+// dispatch2Name = name;
+// } else if (Modifier.isPrivate(modifiers)) {
+// dispatch2Name =
+// AstUtil.makeAjcMangledName("dispatch2".toCharArray(), withinType, selector);
+// } else {
+// // package visible
+// //??? optimize both in same package
+// dispatch2Name =
+// AstUtil.makeAjcMangledName("dispatch2".toCharArray(),
+// withinType.qualifiedPackageName(), selector);
+// }
+//
+// introducedMethod =
+// new MethodBinding(AstUtil.makePublic(modifiers), dispatch2Name,
+// type, args, exceptions, declaringClass);
+//
+// this.dispatchMethod =
+// new DispatchMethodBinding(introducedMethod, withinType, mangledParams);
+// }
+
+
+ //XXX this is identical to InterTypeFieldBinding
+ public boolean canBeSeenBy(TypeBinding receiverType, InvocationSite invocationSite, Scope scope) {
+ if (isPublic()) return true;
+
+ SourceTypeBinding invocationType = scope.invocationType();
+ //System.out.println("receiver: " + receiverType + ", " + invocationType);
+
+ if (invocationType == declaringClass) return true;
+
+
+ // if (invocationType.isPrivileged) {
+ // System.out.println("privileged access to: " + this);
+ // return true;
+ // }
+
+ if (isProtected()) {
+ throw new RuntimeException("unimplemented");
+ }
+
+ //XXX make sure this walks correctly
+ if (isPrivate()) {
+ // answer true if the receiverType is the declaringClass
+ // AND the invocationType and the declaringClass have a common enclosingType
+ //if (receiverType != declaringClass) return false;
+
+ if (invocationType != declaringClass) {
+ ReferenceBinding outerInvocationType = invocationType;
+ ReferenceBinding temp = outerInvocationType.enclosingType();
+ while (temp != null) {
+ outerInvocationType = temp;
+ temp = temp.enclosingType();
+ }
+
+ ReferenceBinding outerDeclaringClass = declaringClass;
+ temp = outerDeclaringClass.enclosingType();
+ while (temp != null) {
+ outerDeclaringClass = temp;
+ temp = temp.enclosingType();
+ }
+
+ //System.err.println("outer dec: " +
+ if (outerInvocationType != outerDeclaringClass) return false;
+ }
+ return true;
+ }
+
+ // isDefault()
+ if (invocationType.fPackage == declaringClass.fPackage) return true;
+ return false;
+ }
+
+
+ public MethodBinding getAccessMethod() {
+ return syntheticMethod;
+ }
+
+ public boolean alwaysNeedsAccessMethod() { return true; }
+
+ public AbstractMethodDeclaration sourceMethod() {
+ return sourceMethod;
+ }
+
+ public ReferenceBinding getTargetType() {
+ return targetType;
+ }
+
+ public String toString() {
+ return "InterTypeMethodBinding(" + super.toString() + ", " + getTargetType() +")";
+ }
+}
diff --git a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/InterTypeScope.java b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/InterTypeScope.java
new file mode 100644
index 000000000..05bddbd58
--- /dev/null
+++ b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/InterTypeScope.java
@@ -0,0 +1,51 @@
+/* *******************************************************************
+ * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC).
+ * All rights reserved.
+ * This program and the accompanying materials are made available
+ * under the terms of the Common Public License v1.0
+ * which accompanies this distribution and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * Xerox/PARC initial implementation
+ * ******************************************************************/
+
+
+package org.aspectj.ajdt.internal.compiler.lookup;
+
+import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
+import org.eclipse.jdt.internal.compiler.lookup.*;
+
+public class InterTypeScope extends ClassScope {
+
+ public InterTypeScope(Scope parent, TypeBinding onType) {
+ super(parent, null);
+ if (onType instanceof SourceTypeBinding) {
+ referenceContext = new TypeDeclaration(null);
+ referenceContext.binding = ((SourceTypeBinding)onType);
+ } else {
+ throw new RuntimeException("unimplemented");
+ }
+ //System.out.println("encolsingSource: " + this.enclosingSourceType());
+ }
+
+ public FieldBinding findField(
+ TypeBinding receiverType,
+ char[] fieldName,
+ InvocationSite invocationSite)
+ {
+ //System.out.println("find: " + new String(fieldName));
+ return super.findField(receiverType, fieldName, invocationSite);
+ }
+
+ public SourceTypeBinding invocationType() {
+ return parent.enclosingSourceType();
+ }
+
+ public int addDepth() {
+ return 0;
+ }
+
+
+
+}
diff --git a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/PointcutBinding.java b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/PointcutBinding.java
new file mode 100644
index 000000000..c63086c40
--- /dev/null
+++ b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/PointcutBinding.java
@@ -0,0 +1,36 @@
+/* *******************************************************************
+ * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC).
+ * All rights reserved.
+ * This program and the accompanying materials are made available
+ * under the terms of the Common Public License v1.0
+ * which accompanies this distribution and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * Xerox/PARC initial implementation
+ * ******************************************************************/
+
+
+package org.aspectj.ajdt.internal.compiler.lookup;
+
+import org.eclipse.jdt.internal.compiler.lookup.*;
+
+/**
+ */
+public class PointcutBinding extends Binding {
+
+ /**
+ * @see org.eclipse.jdt.internal.compiler.lookup.Binding#bindingType()
+ */
+ public int bindingType() {
+ return 0;
+ }
+
+ /**
+ * @see org.eclipse.jdt.internal.compiler.lookup.Binding#readableName()
+ */
+ public char[] readableName() {
+ return null;
+ }
+
+}
diff --git a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/PrivilegedFieldBinding.java b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/PrivilegedFieldBinding.java
new file mode 100644
index 000000000..bd5ac958a
--- /dev/null
+++ b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/PrivilegedFieldBinding.java
@@ -0,0 +1,68 @@
+/* *******************************************************************
+ * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC).
+ * All rights reserved.
+ * This program and the accompanying materials are made available
+ * under the terms of the Common Public License v1.0
+ * which accompanies this distribution and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * Xerox/PARC initial implementation
+ * ******************************************************************/
+
+
+package org.aspectj.ajdt.internal.compiler.lookup;
+
+import java.lang.reflect.Modifier;
+
+import org.aspectj.ajdt.internal.compiler.ast.*;
+import org.aspectj.ajdt.internal.compiler.ast.AstUtil;
+import org.aspectj.weaver.*;
+import org.aspectj.weaver.NameMangler;
+import org.eclipse.jdt.internal.compiler.ast.FieldDeclaration;
+import org.eclipse.jdt.internal.compiler.impl.Constant;
+import org.eclipse.jdt.internal.compiler.lookup.*;
+import org.eclipse.jdt.internal.compiler.util.CharOperation;
+
+public class PrivilegedFieldBinding extends FieldBinding {
+ public SimpleSyntheticAccessMethodBinding reader;
+ public SimpleSyntheticAccessMethodBinding writer;
+
+
+ public FieldBinding baseField;
+
+ public PrivilegedFieldBinding(AspectDeclaration inAspect, FieldBinding baseField) {
+ super(baseField, baseField.declaringClass);
+
+ this.reader = new SimpleSyntheticAccessMethodBinding(
+ inAspect.world.makeMethodBinding(
+ AjcMemberMaker.privilegedAccessMethodForFieldGet(
+ inAspect.typeX, inAspect.world.makeResolvedMember(baseField)
+ )));
+ this.writer = new SimpleSyntheticAccessMethodBinding(inAspect.world.makeMethodBinding(
+ AjcMemberMaker.privilegedAccessMethodForFieldSet(
+ inAspect.typeX, inAspect.world.makeResolvedMember(baseField)
+ )));
+ }
+
+
+ public boolean canBeSeenBy(TypeBinding receiverType, InvocationSite invocationSite, Scope scope) {
+ return true;
+
+ }
+
+
+ public SyntheticAccessMethodBinding getAccessMethod(boolean isReadAccess) {
+ if (isReadAccess) return reader;
+ else return writer;
+ }
+
+ public boolean alwaysNeedsAccessMethod(boolean isReadAccess) { return true; }
+
+
+
+// public ReferenceBinding getTargetType() {
+// return introducedField.declaringClass;
+// }
+
+}
diff --git a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/PrivilegedHandler.java b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/PrivilegedHandler.java
new file mode 100644
index 000000000..dfa8af816
--- /dev/null
+++ b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/PrivilegedHandler.java
@@ -0,0 +1,63 @@
+/* *******************************************************************
+ * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC).
+ * All rights reserved.
+ * This program and the accompanying materials are made available
+ * under the terms of the Common Public License v1.0
+ * which accompanies this distribution and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * Xerox/PARC initial implementation
+ * ******************************************************************/
+
+
+package org.aspectj.ajdt.internal.compiler.lookup;
+
+import java.util.*;
+
+import org.aspectj.ajdt.internal.compiler.ast.AspectDeclaration;
+import org.aspectj.weaver.*;
+import org.eclipse.jdt.internal.compiler.lookup.*;
+
+
+
+public class PrivilegedHandler implements IPrivilegedHandler {
+ private AspectDeclaration inAspect;
+ private Map accessors = new HashMap();
+
+ public PrivilegedHandler(AspectDeclaration inAspect) {
+ this.inAspect = inAspect;
+ }
+
+ public FieldBinding getPrivilegedAccessField(FieldBinding baseField) {
+ ResolvedMember key = inAspect.world.makeResolvedMember(baseField);
+ if (accessors.containsKey(key)) return (FieldBinding)accessors.get(key);
+ FieldBinding ret = new PrivilegedFieldBinding(inAspect, baseField);
+ accessors.put(key, ret);
+ return ret;
+ }
+
+ public MethodBinding getPrivilegedAccessMethod(MethodBinding baseMethod) {
+ ResolvedMember key = inAspect.world.makeResolvedMember(baseMethod);
+ if (accessors.containsKey(key)) return (MethodBinding)accessors.get(key);
+ MethodBinding ret = inAspect.world.makeMethodBinding(
+ AjcMemberMaker.privilegedAccessMethodForMethod(inAspect.typeX, key)
+ );
+
+ //new PrivilegedMethodBinding(inAspect, baseMethod);
+ accessors.put(key, ret);
+ return ret;
+ }
+
+ public ResolvedMember[] getMembers() {
+ Collection m = accessors.keySet();
+ int len = m.size();
+ ResolvedMember[] ret = new ResolvedMember[len];
+ int index = 0;
+ for (Iterator i = m.iterator(); i.hasNext(); ) {
+ ret[index++] = (ResolvedMember)i.next();
+ }
+ return ret;
+ }
+
+}
diff --git a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/SimpleSyntheticAccessMethodBinding.java b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/SimpleSyntheticAccessMethodBinding.java
new file mode 100644
index 000000000..8f238a428
--- /dev/null
+++ b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/SimpleSyntheticAccessMethodBinding.java
@@ -0,0 +1,27 @@
+/* *******************************************************************
+ * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC).
+ * All rights reserved.
+ * This program and the accompanying materials are made available
+ * under the terms of the Common Public License v1.0
+ * which accompanies this distribution and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * Xerox/PARC initial implementation
+ * ******************************************************************/
+
+
+package org.aspectj.ajdt.internal.compiler.lookup;
+
+import org.eclipse.jdt.internal.compiler.lookup.*;
+
+public class SimpleSyntheticAccessMethodBinding extends SyntheticAccessMethodBinding {
+ public SimpleSyntheticAccessMethodBinding(MethodBinding method) {
+ super(method);
+ this.declaringClass = method.declaringClass;
+// this.selector = method.selector;
+// this.modifiers = method.modifiers;
+// this.parameters = method.parameters;
+// this.returnType = method.returnType;
+ }
+}
diff --git a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/parser/AjParser.java b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/parser/AjParser.java
new file mode 100644
index 000000000..40d65731e
--- /dev/null
+++ b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/parser/AjParser.java
@@ -0,0 +1,2251 @@
+/* *******************************************************************
+ * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC).
+ * All rights reserved.
+ * This program and the accompanying materials are made available
+ * under the terms of the Common Public License v1.0
+ * which accompanies this distribution and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * Xerox/PARC initial implementation
+ * ******************************************************************/
+
+
+package org.aspectj.ajdt.internal.compiler.parser;
+
+import java.lang.reflect.Modifier;
+import java.util.*;
+
+import org.aspectj.ajdt.internal.compiler.ast.*;
+import org.aspectj.ajdt.internal.core.builder.EclipseSourceContext;
+import org.aspectj.weaver.*;
+import org.aspectj.weaver.AdviceKind;
+import org.aspectj.weaver.patterns.Declare;
+import org.eclipse.jdt.internal.compiler.CompilationResult;
+import org.eclipse.jdt.internal.compiler.ast.*;
+import org.eclipse.jdt.internal.compiler.parser.*;
+import org.eclipse.jdt.internal.compiler.problem.*;
+import org.eclipse.jdt.internal.compiler.util.CharOperation;
+import org.eclipse.jdt.internal.core.util.CharArrayOps;
+
+
+
+public class AjParser extends Parser {
+ //===DATA===DATA===DATA===DATA===DATA===DATA===//
+ public final static byte rhs[] = {0,
+ 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
+ 2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,
+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+ 1,1,1,1,2,2,1,1,1,1,1,1,1,1,1,
+ 1,1,1,1,3,1,1,1,3,4,0,1,2,1,1,
+ 1,1,1,1,1,1,1,5,1,2,1,2,2,2,1,
+ 1,2,2,2,4,1,1,1,1,2,1,1,1,1,1,
+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+ 1,1,1,2,4,3,5,0,2,1,3,1,2,0,2,
+ 1,3,5,4,1,1,2,5,4,2,6,3,3,4,3,
+ 1,0,1,3,1,1,1,1,2,4,6,2,2,3,5,
+ 7,0,4,1,3,3,1,2,1,1,1,1,1,1,1,
+ 1,1,1,1,1,1,1,1,1,1,1,4,1,1,1,
+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+ 1,1,1,2,3,3,2,2,1,3,1,3,1,2,1,
+ 1,1,3,0,3,1,1,1,1,1,1,1,4,1,3,
+ 3,7,0,0,0,0,0,2,1,1,1,2,2,4,4,
+ 5,4,4,2,1,2,3,3,3,1,3,3,1,3,1,
+ 4,0,2,1,2,2,4,1,1,2,5,5,7,7,7,
+ 7,2,2,3,2,2,3,1,2,1,2,1,1,2,2,
+ 1,1,1,1,1,3,3,4,1,3,4,0,1,2,1,
+ 1,1,1,2,3,4,0,1,1,1,1,1,1,1,1,
+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+ 1,3,3,2,1,1,1,1,1,1,1,5,7,7,6,
+ 2,3,3,4,1,2,2,1,2,3,2,5,5,7,9,
+ 9,1,1,1,1,3,3,5,2,3,2,3,3,3,5,
+ 1,3,4,1,2,5,2,1,1,1,1,1,1,3,1,
+ 1,3,3,3,3,3,1,1,5,6,8,7,2,0,2,
+ 0,1,3,4,4,1,2,3,2,1,1,2,2,3,3,
+ 4,6,6,4,4,1,1,1,1,2,2,0,1,1,3,
+ 3,1,3,3,1,3,3,1,5,5,4,1,3,3,3,
+ 1,3,3,1,3,3,3,1,3,3,3,3,3,1,3,
+ 3,1,3,1,3,1,3,1,3,1,3,1,5,1,1,
+ 3,3,1,1,1,1,1,1,1,1,1,1,1,1,1,
+ 1,1,1,1,1,0,1,0,1,0,1,0,1,0,1,
+ 0,1,0,2,0,1,0,1,0,1,0,1,0,1,0,
+ 1,0,1,0,2,0,0,1,0,1,0,1,0,1,0,
+ 1
+ };
+
+
+ public static char asbStatic[] = null;
+ public static char asrStatic[] = null;
+ public static char symbol_indexStatic[] = null;
+
+ public final static String name[] = { null,
+ "++",
+ "--",
+ "==",
+ "<=",
+ ">=",
+ "!=",
+ "<<",
+ ">>",
+ ">>>",
+ "+=",
+ "-=",
+ "*=",
+ "/=",
+ "&=",
+ "|=",
+ "^=",
+ "%=",
+ "<<=",
+ ">>=",
+ ">>>=",
+ "||",
+ "&&",
+ "+",
+ "-",
+ "!",
+ "%",
+ "^",
+ "&",
+ "*",
+ "|",
+ "~",
+ "/",
+ ">",
+ "<",
+ "(",
+ ")",
+ "{",
+ "}",
+ "[",
+ "]",
+ ";",
+ "?",
+ ":",
+ ",",
+ ".",
+ "=",
+ "",
+ "$empty",
+ "Identifier",
+ "abstract",
+ "assert",
+ "boolean",
+ "break",
+ "byte",
+ "case",
+ "catch",
+ "char",
+ "class",
+ "continue",
+ "default",
+ "do",
+ "double",
+ "else",
+ "extends",
+ "false",
+ "final",
+ "finally",
+ "float",
+ "for",
+ "if",
+ "implements",
+ "import",
+ "instanceof",
+ "int",
+ "interface",
+ "long",
+ "native",
+ "new",
+ "null",
+ "package",
+ "private",
+ "protected",
+ "public",
+ "return",
+ "short",
+ "static",
+ "strictfp",
+ "super",
+ "switch",
+ "synchronized",
+ "this",
+ "throw",
+ "throws",
+ "transient",
+ "true",
+ "try",
+ "void",
+ "volatile",
+ "while",
+ "aspect",
+ "pointcut",
+ "around",
+ "before",
+ "after",
+ "declare",
+ "privileged",
+ "IntegerLiteral",
+ "LongLiteral",
+ "FloatingPointLiteral",
+ "DoubleLiteral",
+ "CharacterLiteral",
+ "StringLiteral",
+ UNEXPECTED_EOF,
+ "Invalid Character",
+ "Goal",
+ "MethodBody",
+ "ConstructorBody",
+ "StaticInitializer",
+ "Initializer",
+ "Headers",
+ "BlockStatements",
+ "MethodPushModifiersHeader",
+ "CatchHeader",
+ "FieldDeclaration",
+ "ImportDeclaration",
+ "PackageDeclaration",
+ "TypeDeclaration",
+ "GenericMethodDeclaration",
+ "ClassBodyDeclaration",
+ "Expression",
+ "JavaIdentifier",
+ "AjSimpleName",
+ "JavaIdentifierNoAround",
+ "AjSimpleNameNoAround",
+ "Type",
+ "PrimitiveType",
+ "ReferenceType",
+ "ClassOrInterfaceType",
+ "ArrayType",
+ "Name",
+ "Dims",
+ "ClassType",
+ "NameOrAj",
+ "AjName",
+ "SimpleName",
+ "Header",
+ "ClassHeader",
+ "InterfaceHeader",
+ "MethodHeader",
+ "ConstructorHeader",
+ "FormalParameter",
+ "ImportDeclarations",
+ "TypeDeclarations",
+ "PackageDeclarationName",
+ "SingleTypeImportDeclarationNam" +
+ "e",
+ "TypeImportOnDemandDeclarationN" +
+ "ame",
+ "Modifiers",
+ "Modifier",
+ "InterfaceMemberDeclaration",
+ "AspectHeader",
+ "AspectBody",
+ "AspectHeaderName",
+ "AspectHeaderRestStart",
+ "PseudoTokens",
+ "AspectBodyDeclarations",
+ "AspectBodyDeclaration",
+ "PointcutHeader",
+ "MethodHeaderParameters",
+ "AroundHeader",
+ "AroundHeaderName",
+ "BasicAdviceHeader",
+ "BasicAdviceHeaderName",
+ "OnType",
+ "InterTypeMethodHeader",
+ "InterTypeMethodHeaderName",
+ "InterTypeConstructorHeader",
+ "InterTypeConstructorHeaderName",
+ "VariableInitializer",
+ "DeclareHeader",
+ "PseudoToken",
+ "ClassBody",
+ "ClassHeaderName",
+ "InterfaceTypeList",
+ "InterfaceType",
+ "ClassBodyDeclarations",
+ "Block",
+ "VariableDeclarators",
+ "VariableDeclarator",
+ "VariableDeclaratorId",
+ "ArrayInitializer",
+ "MethodHeaderName",
+ "MethodPushModifiersHeaderName",
+ "ClassTypeList",
+ "ConstructorHeaderName",
+ "FormalParameterList",
+ "ClassTypeElt",
+ "StaticOnly",
+ "ExplicitConstructorInvocation",
+ "Primary",
+ "InterfaceBody",
+ "InterfaceHeaderName",
+ "InterfaceMemberDeclarations",
+ "VariableInitializers",
+ "BlockStatement",
+ "Statement",
+ "LocalVariableDeclaration",
+ "StatementWithoutTrailingSubsta" +
+ "tement",
+ "StatementNoShortIf",
+ "StatementExpression",
+ "PostIncrementExpression",
+ "PostDecrementExpression",
+ "MethodInvocation",
+ "ClassInstanceCreationExpressio" +
+ "n",
+ "SwitchBlock",
+ "SwitchBlockStatements",
+ "SwitchLabels",
+ "SwitchBlockStatement",
+ "SwitchLabel",
+ "ConstantExpression",
+ "StatementExpressionList",
+ "OnlySynchronized",
+ "Catches",
+ "Finally",
+ "CatchClause",
+ "PushLPAREN",
+ "PushRPAREN",
+ "PrimaryNoNewArray",
+ "FieldAccess",
+ "ArrayAccess",
+ "ClassInstanceCreationExpressio" +
+ "nName",
+ "ArgumentList",
+ "DimWithOrWithOutExprs",
+ "DimWithOrWithOutExpr",
+ "DimsLoop",
+ "OneDimLoop",
+ "PostfixExpression",
+ "UnaryExpression",
+ "UnaryExpressionNotPlusMinus",
+ "MultiplicativeExpression",
+ "AdditiveExpression",
+ "ShiftExpression",
+ "RelationalExpression",
+ "EqualityExpression",
+ "AndExpression",
+ "ExclusiveOrExpression",
+ "InclusiveOrExpression",
+ "ConditionalAndExpression",
+ "ConditionalOrExpression",
+ "ConditionalExpression",
+ "AssignmentExpression",
+ "LeftHandSide",
+ "AssignmentOperator"
+ };
+
+ public static short check_tableStatic[] = null;
+ public static char lhsStatic[] = null;
+ public static char actionStatic[] = lhsStatic;
+
+ protected void initData() {
+ rhsInst = rhs;
+ asb = asbStatic;
+ asr = asrStatic;
+ symbol_index = symbol_indexStatic;
+ nameInst = name;
+ check_table = check_tableStatic;
+ lhs = lhsStatic;
+ action = actionStatic;
+ }
+
+ static {
+ try{
+ initAjTables(AjParser.class);
+ } catch(java.io.IOException ex){
+ throw new ExceptionInInitializerError(ex.getMessage());
+ }
+ }
+
+ public final static void initAjTables(Class parserClass)
+ throws java.io.IOException {
+
+ final String prefix = FILEPREFIX;
+ int i = 0;
+ lhsStatic = readTable(parserClass, prefix + (++i) + ".rsc"); //$NON-NLS-1$
+ char[] chars = readTable(parserClass, prefix + (++i) + ".rsc"); //$NON-NLS-1$
+ check_tableStatic = new short[chars.length];
+ for (int c = chars.length; c-- > 0;) {
+ check_tableStatic[c] = (short) (chars[c] - 32768);
+ }
+ asbStatic = readTable(parserClass, prefix + (++i) + ".rsc"); //$NON-NLS-1$
+ asrStatic = readTable(parserClass, prefix + (++i) + ".rsc"); //$NON-NLS-1$
+ symbol_indexStatic = readTable(parserClass, prefix + (++i) + ".rsc"); //$NON-NLS-1$
+ actionStatic = lhsStatic;
+ }
+
+
+ public void initializeScanner(){
+ this.scanner = new AjScanner(false, false, this.problemReporter.options.getNonExternalizedStringLiteralSeverity() != ProblemSeverities.Ignore , this.assertMode);
+ }
+
+
+
+//*************New display debugging method
+ private static final boolean AJ_DEBUG = false;
+
+ void println(Object o) {
+ if (AJ_DEBUG) System.out.println(o);
+ }
+
+ private void printStack(Object[] s, int p) {
+ List list = Arrays.asList(s);
+ System.out.println(" " + list.subList(0, p+1));
+ }
+
+ private void printStack(int[] s, int p) {
+ StringBuffer buf = new StringBuffer("[");
+ for (int i=0; i<p+1; i++) {
+ if (i > 0) buf.append(", ");
+ buf.append(Integer.toString(s[i]));
+ }
+ buf.append("]");
+ System.out.println(" " + buf);
+ }
+
+ private void printStack(long[] s, int p) {
+ StringBuffer buf = new StringBuffer("[");
+ for (int i=0; i<p+1; i++) {
+ if (i > 0) buf.append(", ");
+ buf.append(Long.toString(s[i]));
+ }
+ buf.append("]");
+ System.out.println(" " + buf);
+ }
+
+ private void printStack(char[][] s, int p) {
+ StringBuffer buf = new StringBuffer("[");
+ for (int i=0; i<p+1; i++) {
+ if (i > 0) buf.append(", ");
+ buf.append(new String(s[i]));
+ }
+ buf.append("]");
+ System.out.println(" " + buf);
+ }
+
+ public void display() {
+ if (!AJ_DEBUG) return;
+ System.out.print("astStack: ");
+ printStack(astStack, astPtr);
+ System.out.print("astLengthStack: ");
+ printStack(astLengthStack, astLengthPtr);
+
+ System.out.print("expressionStack: ");
+ printStack(expressionStack, expressionPtr);
+ System.out.print("expressionLengthStack: ");
+ printStack(expressionLengthStack, expressionLengthPtr);
+
+ System.out.print("identifierStack: ");
+ printStack(identifierStack, identifierPtr);
+ System.out.print("identifierLengthStack: ");
+ printStack(identifierLengthStack, identifierLengthPtr);
+ System.out.print("identifierPositionStack: ");
+ printStack(identifierPositionStack, identifierPtr);
+
+
+ System.out.print("intStack:");
+ printStack(intStack, intPtr);
+ System.out.println();
+ }
+
+
+
+//************** Overriding behavior for standard Java rules
+ protected void consumeMethodInvocationName() {
+ super.consumeMethodInvocationName();
+
+ MessageSend m = (MessageSend)expressionStack[expressionPtr];
+ if (CharArrayOps.equals(m.selector, "proceed".toCharArray())) {
+ expressionStack[expressionPtr] = new Proceed(m);
+ }
+ }
+
+ protected void consumeToken(int type) {
+ currentTokenStart = scanner.startPosition;
+ super.consumeToken(type);
+ switch (type) {
+ case TokenNameaspect : // pseudo keyword
+ case TokenNameprivileged : // pseudo keyword
+ case TokenNamepointcut : // pseudo keyword
+ case TokenNamebefore : // pseudo keyword
+ case TokenNameafter : // pseudo keyword
+ case TokenNamearound : // pseudo keyword
+ case TokenNamedeclare : // pseudo keyword
+ pushIdentifier();
+ scanner.commentPtr = -1;
+ break;
+ }
+ }
+
+
+//************New AspectJ rules
+ protected void consumeAspectDeclaration() {
+ // AspectDeclaration ::= AspectHeader AspectBody
+ consumeClassDeclaration();
+ //??? post parsing step here
+ }
+
+ protected void consumeAspectHeader() {
+ // AspectHeader ::= AspectHeaderName ClassHeaderExtendsopt ClassHeaderImplementsopt AspectHeaderRest
+ consumeClassHeader();
+ }
+
+ protected void consumeAspectHeaderName(boolean isPrivileged) {
+ // (isPrivileged == false) -> AspectHeaderName ::= Modifiersopt 'aspect' 'Identifier'
+ // (isPrivileged == true) -> AspectHeaderName ::= Modifiersopt 'privileged' Modifiersopt 'aspect' 'Identifier'
+ AspectDeclaration aspectDecl =
+ new AspectDeclaration(this.compilationUnit.compilationResult);
+
+ println("aspect header name: ");
+ this.display();
+
+ //highlight the name of the type
+ long pos = identifierPositionStack[identifierPtr];
+ aspectDecl.sourceEnd = (int) pos;
+ aspectDecl.sourceStart = (int) (pos >>> 32);
+ aspectDecl.name = identifierStack[identifierPtr--];
+ identifierLengthPtr--;
+
+ // pop the aspect pseudo-token
+ eatIdentifier();
+
+
+ // handle modifiers, only without privileged for now
+ if (isPrivileged) {
+ pos = eatIdentifier(); // eat the privileged
+ int end = (int) pos;
+ int start = (int) (pos >>> 32);
+ aspectDecl.isPrivileged = true;
+ //problemReporter().signalError(start, end, "privileged is unimplemented in 1.1alpha1");
+ }
+ aspectDecl.modifiersSourceStart = intStack[intPtr--];
+ aspectDecl.modifiers = intStack[intPtr--];
+ if (aspectDecl.modifiersSourceStart >= 0) {
+ aspectDecl.declarationSourceStart = aspectDecl.modifiersSourceStart;
+ }
+
+ println("modifiers: " + aspectDecl.modifiers);
+
+ aspectDecl.bodyStart = aspectDecl.sourceEnd + 1;
+ pushOnAstStack(aspectDecl);
+
+ listLength = 0; // will be updated when reading super-interfaces
+ // recovery
+ if (currentElement != null) {
+ lastCheckPoint = aspectDecl.bodyStart;
+ currentElement = currentElement.add(aspectDecl, 0);
+ lastIgnoredToken = -1;
+ }
+
+ this.display();
+ }
+
+ private long eatIdentifier() {
+ long pos = identifierPositionStack[identifierPtr];
+ identifierPtr--;
+ identifierLengthPtr--;
+ return pos;
+ }
+
+ protected void consumeAspectHeaderRest() {
+ //--[dominates TypePattern] [persingleton() | percflow(PCD) | perthis(PCD) | pertarget(PCD)]
+ //AspectHeaderRest ::= AspectHeaderRestStart PseudoTokens
+ concatNodeLists();
+ this.display();
+ PseudoTokens pseudoTokens = popPseudoTokens("{");
+ println("pseudo: " + pseudoTokens);
+
+ AspectDeclaration aspectDecl = (AspectDeclaration) astStack[astPtr];
+
+ aspectDecl.dominatesPattern = pseudoTokens.maybeParseDominatesPattern(this);
+ aspectDecl.perClause = pseudoTokens.parsePerClause(this);
+ // XXX handle dominates
+ }
+
+
+ protected void consumePointcutDeclaration() {
+ consumePointcutDesignatorOnDeclaration();
+ }
+
+ protected void consumeEmptyPointcutDeclaration() {
+ //??? set pcd to non-null
+ }
+
+ protected void consumePointcutHeader() {
+ //PointcutDeclaration ::= Modifiersopt 'pointcut' JavaIdentifier '('
+
+ PointcutDeclaration ret = new PointcutDeclaration(compilationUnit.compilationResult);
+
+ //the name
+ long pos = identifierPositionStack[identifierPtr];
+ int sourceEnd = (int) pos;
+ ret.sourceStart = (int) (pos >>> 32);
+ ret.selector = identifierStack[identifierPtr--];
+ identifierLengthPtr--;
+
+ // pop the 'pointcut' keyword
+ eatIdentifier();
+
+ // modifiers
+ ret.declarationSourceStart = intStack[intPtr--];
+ ret.modifiers = intStack[intPtr--];
+
+ pushOnAstStack(ret);
+ }
+
+
+
+ protected void consumeAroundDeclaration() {
+ // AroundDeclaration ::= AroundHeader MethodBody
+ consumeMethodDeclaration(true);
+ }
+
+ protected void consumeAroundHeader() {
+ consumePointcutDesignatorOnAdvice();
+ }
+
+ protected void consumeAroundHeaderName() {
+ // AroundHeaderName ::= Modifiersopt Type 'around' '('
+
+ AdviceDeclaration adviceDecl =
+ new AdviceDeclaration(compilationUnit.compilationResult, AdviceKind.Around);
+
+ // skip the name of the advice
+ long pos = eatIdentifier();
+ adviceDecl.sourceStart = (int) (pos >>> 32);
+
+ TypeReference returnType = getTypeReference(intStack[intPtr--]);
+
+ //modifiers
+ adviceDecl.declarationSourceStart = intStack[intPtr--];
+ adviceDecl.modifiers = intStack[intPtr--];
+
+ adviceDecl.returnType = returnType;
+
+ //XXX get some locations right
+
+ pushOnAstStack(adviceDecl);
+ }
+
+ protected void consumePointcutDesignatorOnAdvice() {
+ PointcutDesignator des = popPointcutDesignator("{");
+ AdviceDeclaration adviceDecl = (AdviceDeclaration)astStack[astPtr];
+ adviceDecl.pointcutDesignator = des;
+ adviceDecl.sourceEnd = des.sourceEnd;
+ adviceDecl.bodyStart = des.sourceEnd+1;
+ }
+
+ protected void consumePointcutDesignatorOnDeclaration() {
+ PointcutDesignator des = popPointcutDesignator(";");
+ PointcutDeclaration adviceDecl = (PointcutDeclaration)astStack[astPtr];
+ adviceDecl.pointcutDesignator = des;
+ adviceDecl.sourceEnd = des.sourceEnd;
+ adviceDecl.bodyStart = des.sourceEnd+1;
+ }
+
+
+ protected void consumeBasicAdviceDeclaration() {
+ // BasicAdviceDeclaration ::= BasicAdviceHeader MethodBody
+ consumeMethodDeclaration(true);
+ }
+
+ protected void consumeBasicAdviceHeader() {
+ // BasicAdviceHeader ::= BasicAdviceHeaderName MethodHeaderParameters ExtraParamopt MethodHeaderThrowsClauseopt ':' PseudoTokens
+ consumePointcutDesignatorOnAdvice();
+ }
+
+
+ protected void consumeBasicAdviceHeaderName(boolean isAfter) {
+ // BasicAdviceHeaderName ::= 'before'|'after '('
+
+ AdviceDeclaration adviceDecl =
+ new AdviceDeclaration(compilationUnit.compilationResult, isAfter ? AdviceKind.After : AdviceKind.Before);
+
+ // skip the name of the advice
+ long pos = eatIdentifier();
+ adviceDecl.sourceStart = (int) (pos >>> 32);
+
+ //modifiers
+ adviceDecl.declarationSourceStart = intStack[intPtr--];
+ adviceDecl.modifiers = intStack[intPtr--];
+
+
+ //??? get more locations right
+
+ pushOnAstStack(adviceDecl);
+ }
+
+ protected void consumeExtraParameterWithFormal() {
+ Argument arg = (Argument)astStack[astPtr--];
+ astLengthPtr--;
+
+ ((AdviceDeclaration)astStack[astPtr]).extraArgument = arg;
+
+ consumeExtraParameterNoFormal();
+ }
+
+
+ protected void consumeExtraParameterNoFormal() {
+
+
+ long pos = identifierPositionStack[identifierPtr];
+ int end = (int) pos;
+ int start = (int) (pos >>> 32);
+ char[] name = identifierStack[identifierPtr--];
+ identifierLengthPtr--;
+
+ //System.out.println("extra parameter: " + new String(name));
+
+ AdviceDeclaration adviceDecl = (AdviceDeclaration)astStack[astPtr];
+ if (adviceDecl.kind != AdviceKind.After) {
+ //XXX error, extra param makes no sense here
+ }
+
+ if (CharOperation.equals(name, "throwing".toCharArray())) {
+ adviceDecl.kind = AdviceKind.AfterThrowing;
+ } else if (CharOperation.equals(name, "returning".toCharArray())) {
+ adviceDecl.kind = AdviceKind.AfterReturning;
+ } else {
+ //XXX illegal name here
+ }
+ }
+
+ protected void consumeClassBodyDeclarationInAspect() { }
+
+
+ protected void consumeDeclareDeclaration() {
+ concatNodeLists();
+ PseudoTokens tokens = popPseudoTokens(";");
+ Declare declare = tokens.parseDeclare(this);
+ println("parsed declare: " + declare);
+ display();
+ pushOnAstStack(new DeclareDeclaration(this.compilationUnit.compilationResult, declare));
+ }
+
+
+
+
+ protected void consumeDeclareHeader() {
+ consumePseudoTokenIdentifier(); // name
+ consumePseudoTokenIdentifier(); // declare
+ swapAstStack();
+ consumePseudoTokens();
+
+ consumePseudoToken(":", 0, false);
+ consumePseudoTokens();
+
+ println(">>>>>>>>>>>>>>>>>>>>>>>declare header");
+ display();
+ }
+
+
+ protected void consumeInterTypeFieldDeclaration() {
+ // InterTypeFieldDeclaration ::= Modifiersopt Type OnType '.' JavaIdentifier InterTypeFieldBody ';'
+ println("about to consume field");
+ this.display();
+ // FieldDeclaration field = new FieldDeclaration();
+
+ Expression initialization = null;
+ if (expressionPtr >= 0) {
+ expressionLengthPtr--;
+ initialization = expressionStack[expressionPtr--];
+ }
+
+ long pos = identifierPositionStack[identifierPtr];
+ int end = (int) pos;
+ int start = (int) (pos >>> 32);
+ char[] name = identifierStack[identifierPtr--];
+ identifierLengthPtr--;
+
+ // field.name = name;
+ // field.sourceStart = start;
+ // field.sourceEnd = end;
+
+ TypeReference onType = getTypeReference(0);
+ TypeReference returnType = getTypeReference(0);
+ // field.type = returnType;
+
+ this.display();
+
+ int dontKnowWhatThisIs = intStack[intPtr--];
+
+ int decSourceStart = intStack[intPtr--];
+ int modifiers = intStack[intPtr--];
+
+ InterTypeFieldDeclaration dec =
+ new InterTypeFieldDeclaration(
+ this.compilationUnit.compilationResult,
+ onType);
+
+ dec.returnType = returnType;
+ dec.sourceStart = start;
+ dec.sourceEnd = end;
+ dec.setSelector(name);
+ dec.declarationSourceStart = decSourceStart;
+ dec.setDeclaredModifiers(modifiers);
+ dec.setInitialization(initialization);
+
+ pushOnAstStack(dec);
+ println("consumed field: " + dec);
+ this.display();
+ }
+
+ protected void consumeInterTypeMethodDeclaration(boolean isNotAbstract) {
+ consumeMethodDeclaration(isNotAbstract);
+ }
+
+ protected void consumeInterTypeMethodHeader() {
+ consumeMethodHeader();
+ }
+
+ protected void consumeInterTypeConstructorDeclaration() {
+ consumeMethodDeclaration(true);
+ }
+
+ protected void consumeInterTypeConstructorHeader() {
+ consumeMethodHeader();
+ }
+
+ protected void consumeInterTypeMethodHeaderName() {
+ //InterTypeMethodHeaderName ::= Modifiersopt Type OnType '.' JavaIdentifier '('
+ this.display();
+ InterTypeMethodDeclaration md =
+ new InterTypeMethodDeclaration(
+ this.compilationUnit.compilationResult,
+ null);
+
+ //identifier
+ char[] name = identifierStack[identifierPtr];
+ long selectorSource = identifierPositionStack[identifierPtr--];
+ identifierLengthPtr--;
+
+ //onType
+ md.onType = getTypeReference(0);
+
+ //type
+ md.returnType = getTypeReference(intStack[intPtr--]);
+
+ //modifiers
+ md.declarationSourceStart = intStack[intPtr--];
+ md.setDeclaredModifiers(intStack[intPtr--]);
+
+ //highlight starts at selector start
+ md.sourceStart = (int) (selectorSource >>> 32);
+ pushOnAstStack(md);
+ md.sourceEnd = lParenPos;
+ md.bodyStart = lParenPos + 1;
+ md.setSelector(name);
+ listLength = 0;
+ // initialize listLength before reading parameters/throws
+
+ // recovery
+ if (currentElement != null) {
+ if (currentElement instanceof RecoveredType
+ //|| md.modifiers != 0
+ || (scanner.getLineNumber(md.returnType.sourceStart)
+ == scanner.getLineNumber(md.sourceStart))) {
+ lastCheckPoint = md.bodyStart;
+ currentElement = currentElement.add(md, 0);
+ lastIgnoredToken = -1;
+ } else {
+ lastCheckPoint = md.sourceStart;
+ restartRecovery = true;
+ }
+ }
+ }
+
+ protected void consumeInterTypeConstructorHeaderName() {
+ //InterTypeConstructorHeaderName ::= Modifiersopt Name '.' 'new' '('
+ this.display();
+ InterTypeConstructorDeclaration md =
+ new InterTypeConstructorDeclaration(
+ this.compilationUnit.compilationResult,
+ null);
+
+ //identifier
+// md.selector = identifierStack[identifierPtr];
+// long selectorSource = identifierPositionStack[identifierPtr--];
+//// identifierLengthPtr--;
+
+ //onType
+ md.onType = getTypeReference(0);
+
+ println("got onType: " + md.onType);
+ this.display();
+
+ intPtr--; // pop new info
+ //type
+ md.returnType = TypeReference.baseTypeReference(T_void, 0); //getTypeReference(intStack[intPtr--]);
+
+ //modifiers
+ md.declarationSourceStart = intStack[intPtr--];
+ md.setDeclaredModifiers(intStack[intPtr--]);
+ //md.modifiers = intStack[intPtr--];
+
+ //highlight starts at selector start
+ //md.sourceStart = (int) (selectorSource >>> 32);
+ md.sourceStart = md.onType.sourceStart;
+ pushOnAstStack(md);
+ md.sourceEnd = lParenPos;
+ md.bodyStart = lParenPos + 1;
+ listLength = 0;
+ // initialize listLength before reading parameters/throws
+
+ md.setSelector(
+ (new String(CharOperation.concatWith(md.onType.getTypeName(), '_')) + "_new").
+ toCharArray());
+
+
+ // recovery
+ if (currentElement != null) {
+ if (currentElement instanceof RecoveredType
+ //|| md.modifiers != 0
+ //|| (scanner.getLineNumber(md.returnType.sourceStart)
+ // == scanner.getLineNumber(md.sourceStart))
+ ) {
+ //lastCheckPoint = md.bodyStart;
+ currentElement = currentElement.add(md, 0);
+ lastIgnoredToken = -1;
+ } else {
+ lastCheckPoint = md.sourceStart;
+ restartRecovery = true;
+ }
+ }
+ }
+
+
+
+
+//*********************************************************
+
+
+ protected void consumePseudoToken(String value) {
+ consumePseudoToken(value, 0, false);
+ }
+
+ protected void consumePseudoToken(
+ String value,
+ int popFromIntStack,
+ boolean isIdentifier) {
+ intPtr -= popFromIntStack;
+
+ int start = currentTokenStart;
+ int end = start + value.length() - 1;
+ PseudoToken tok = new PseudoToken(this, value, isIdentifier);
+ tok.sourceStart = start;
+ tok.sourceEnd = end;
+ pushOnAstStack(tok);
+ }
+
+ protected void consumePseudoTokenIdentifier() {
+ long pos = identifierPositionStack[identifierPtr];
+ int end = (int) pos;
+ int start = (int) (pos >>> 32);
+ char[] name = identifierStack[identifierPtr--];
+ identifierLengthPtr--;
+
+ PseudoToken tok = new PseudoToken(this, new String(name), true);
+ tok.sourceStart = start;
+ tok.sourceEnd = end;
+ pushOnAstStack(tok);
+ }
+
+ protected void consumePseudoTokenIf() {
+ //this.display();
+ Expression expr = (Expression) expressionStack[expressionPtr--];
+ expressionLengthPtr--;
+ println("expr: " + expr);
+
+ int start = intStack[intPtr--];
+ PseudoToken tok = new IfPseudoToken(this, expr);
+ tok.sourceStart = start;
+ tok.sourceEnd = this.rParenPos;
+ pushOnAstStack(tok);
+ }
+
+ protected void consumePseudoTokenLiteral() {
+ Literal literal = (Literal) expressionStack[expressionPtr--];
+ expressionLengthPtr--;
+ //System.out.println("literal: " + new String(literal.source()));
+
+ PseudoToken tok =
+ new PseudoToken(this, new String(literal.source()), false);
+ tok.literalKind = "string";
+ tok.sourceStart = literal.sourceStart;
+ tok.sourceEnd = literal.sourceEnd;
+ pushOnAstStack(tok);
+ }
+
+ protected void consumePseudoTokenModifier() {
+ //int modifier = modifiers;
+ consumePseudoToken(Modifier.toString(modifiers), 0, true);
+ modifiers = AccDefault;
+ }
+
+ protected void consumePseudoTokenPrimitiveType() {
+ TypeReference type = getTypeReference(0);
+
+ PseudoToken tok = new PseudoToken(this, type.toString(), true);
+ tok.sourceStart = type.sourceStart;
+ tok.sourceEnd = type.sourceEnd;
+ pushOnAstStack(tok);
+ }
+
+ protected void consumePseudoTokens() {
+ optimizedConcatNodeLists();
+ }
+
+// Helpers
+
+ protected PointcutDesignator popPointcutDesignator(String terminator) {
+ PseudoTokens tokens = popPseudoTokens(terminator);
+ return new PointcutDesignator(this, tokens);
+ }
+
+ protected PseudoTokens popPseudoTokens(String terminator) {
+ consumePseudoToken(terminator);
+ consumePseudoTokens();
+ //System.out.println("next token is: " + new String(scanner.getCurrentTokenSource()));
+
+ int length = astLengthStack[astLengthPtr--];
+ astPtr -= length;
+
+ //arguments
+ PseudoToken[] tokens = new PseudoToken[length];
+ System.arraycopy(astStack, astPtr + 1, tokens, 0, length);
+ //md.bodyStart = rParenPos+1;
+ listLength = 0; // reset listLength after having read all parameters
+
+ return new PseudoTokens(tokens, makeSourceContext(this.compilationUnit.compilationResult()));
+ }
+
+ private ISourceContext makeSourceContext(CompilationResult compilationResult) {
+ return new EclipseSourceContext(compilationResult);
+ }
+
+
+ private void swapAstStack() {
+ AstNode top = astStack[astPtr];
+ AstNode next = astStack[astPtr-1];
+ astStack[astPtr] = next;
+ astStack[astPtr-1] = top;
+ }
+
+
+
+ // This method is part of an automatic generation : do NOT edit-modify
+ // This method is part of an automatic generation : do NOT edit-modify
+protected void consumeRule(int act) {
+ switch ( act ) {
+ case 33 : // System.out.println("Type ::= PrimitiveType");
+ consumePrimitiveType();
+ break ;
+
+ case 47 : // System.out.println("ReferenceType ::= ClassOrInterfaceType");
+ consumeReferenceType();
+ break ;
+
+ case 65 : // System.out.println("AjQualifiedName ::= AjName DOT SimpleName");
+ consumeQualifiedName();
+ break ;
+
+ case 69 : // System.out.println("QualifiedName ::= Name DOT JavaIdentifier");
+ consumeQualifiedName();
+ break ;
+
+ case 70 : // System.out.println("CompilationUnit ::= EnterCompilationUnit PackageDeclarationopt ImportDeclarationsopt");
+ consumeCompilationUnit();
+ break ;
+
+ case 71 : // System.out.println("EnterCompilationUnit ::=");
+ consumeEnterCompilationUnit();
+ break ;
+
+ case 83 : // System.out.println("CatchHeader ::= catch LPAREN FormalParameter RPAREN LBRACE");
+ consumeCatchHeader();
+ break ;
+
+ case 85 : // System.out.println("ImportDeclarations ::= ImportDeclarations ImportDeclaration");
+ consumeImportDeclarations();
+ break ;
+
+ case 87 : // System.out.println("TypeDeclarations ::= TypeDeclarations TypeDeclaration");
+ consumeTypeDeclarations();
+ break ;
+
+ case 88 : // System.out.println("PackageDeclaration ::= PackageDeclarationName SEMICOLON");
+ consumePackageDeclaration();
+ break ;
+
+ case 89 : // System.out.println("PackageDeclarationName ::= package Name");
+ consumePackageDeclarationName();
+ break ;
+
+ case 92 : // System.out.println("SingleTypeImportDeclaration ::= SingleTypeImportDeclarationName SEMICOLON");
+ consumeSingleTypeImportDeclaration();
+ break ;
+
+ case 93 : // System.out.println("SingleTypeImportDeclarationName ::= import Name");
+ consumeSingleTypeImportDeclarationName();
+ break ;
+
+ case 94 : // System.out.println("TypeImportOnDemandDeclaration ::= TypeImportOnDemandDeclarationName SEMICOLON");
+ consumeTypeImportOnDemandDeclaration();
+ break ;
+
+ case 95 : // System.out.println("TypeImportOnDemandDeclarationName ::= import Name DOT MULTIPLY");
+ consumeTypeImportOnDemandDeclarationName();
+ break ;
+
+ case 98 : // System.out.println("TypeDeclaration ::= SEMICOLON");
+ consumeEmptyTypeDeclaration();
+ break ;
+
+ case 124 : // System.out.println("AspectDeclaration ::= AspectHeader AspectBody");
+ consumeAspectDeclaration();
+ break ;
+
+ case 125 : // System.out.println("AspectHeader ::= AspectHeaderName ClassHeaderExtendsopt ClassHeaderImplementsopt...");
+ consumeAspectHeader();
+ break ;
+
+ case 126 : // System.out.println("AspectHeaderName ::= Modifiersopt aspect Identifier");
+ consumeAspectHeaderName(false);
+ break ;
+
+ case 127 : // System.out.println("AspectHeaderName ::= Modifiersopt privileged Modifiersopt aspect Identifier");
+ consumeAspectHeaderName(true);
+ break ;
+
+ case 129 : // System.out.println("AspectHeaderRest ::= AspectHeaderRestStart PseudoTokens");
+ consumeAspectHeaderRest();
+ break ;
+
+ case 130 : // System.out.println("AspectHeaderRestStart ::= Identifier");
+ consumePseudoTokenIdentifier();
+ break ;
+
+ case 133 : // System.out.println("AspectBodyDeclarations ::= AspectBodyDeclarations AspectBodyDeclaration");
+ consumeClassBodyDeclarations();
+ break ;
+
+ case 134 : // System.out.println("AspectBodyDeclarationsopt ::=");
+ consumeEmptyClassBodyDeclarationsopt();
+ break ;
+
+ case 135 : // System.out.println("AspectBodyDeclarationsopt ::= NestedType AspectBodyDeclarations");
+ consumeClassBodyDeclarationsopt();
+ break ;
+
+ case 136 : // System.out.println("AspectBodyDeclaration ::= ClassBodyDeclaration");
+ consumeClassBodyDeclarationInAspect();
+ break ;
+
+ case 137 : // System.out.println("PointcutDeclaration ::= PointcutHeader MethodHeaderParameters SEMICOLON");
+ consumeEmptyPointcutDeclaration();
+ break ;
+
+ case 138 : // System.out.println("PointcutDeclaration ::= PointcutHeader MethodHeaderParameters COLON PseudoTokens...");
+ consumePointcutDeclaration();
+ break ;
+
+ case 139 : // System.out.println("PointcutHeader ::= Modifiersopt pointcut JavaIdentifier LPAREN");
+ consumePointcutHeader();
+ break ;
+
+ case 142 : // System.out.println("AroundDeclaration ::= AroundHeader MethodBody");
+ consumeAroundDeclaration();
+ break ;
+
+ case 143 : // System.out.println("AroundHeader ::= AroundHeaderName MethodHeaderParameters...");
+ consumeAroundHeader();
+ break ;
+
+ case 144 : // System.out.println("AroundHeaderName ::= Modifiersopt Type around LPAREN");
+ consumeAroundHeaderName();
+ break ;
+
+ case 145 : // System.out.println("BasicAdviceDeclaration ::= BasicAdviceHeader MethodBody");
+ consumeBasicAdviceDeclaration();
+ break ;
+
+ case 146 : // System.out.println("BasicAdviceHeader ::= BasicAdviceHeaderName MethodHeaderParameters ExtraParamopt...");
+ consumeBasicAdviceHeader();
+ break ;
+
+ case 147 : // System.out.println("BasicAdviceHeaderName ::= Modifiersopt before LPAREN");
+ consumeBasicAdviceHeaderName(false);
+ break ;
+
+ case 148 : // System.out.println("BasicAdviceHeaderName ::= Modifiersopt after LPAREN");
+ consumeBasicAdviceHeaderName(true);
+ break ;
+
+ case 149 : // System.out.println("ExtraParamopt ::= Identifier LPAREN FormalParameter RPAREN");
+ consumeExtraParameterWithFormal();
+ break ;
+
+ case 150 : // System.out.println("ExtraParamopt ::= Identifier LPAREN RPAREN");
+ consumeExtraParameterNoFormal();
+ break ;
+
+ case 151 : // System.out.println("ExtraParamopt ::= Identifier");
+ consumeExtraParameterNoFormal();
+ break ;
+
+ case 154 : // System.out.println("OnType ::= OnType DOT JavaIdentifier");
+ consumeQualifiedName();
+ break ;
+
+ case 159 : // System.out.println("InterTypeMethodDeclaration ::= InterTypeMethodHeader MethodBody");
+ // set to true to consume a method with a body
+ consumeInterTypeMethodDeclaration(true);
+ break ;
+
+ case 160 : // System.out.println("InterTypeMethodHeader ::= InterTypeMethodHeaderName MethodHeaderParameters...");
+ consumeInterTypeMethodHeader();
+ break ;
+
+ case 161 : // System.out.println("InterTypeMethodHeaderName ::= Modifiersopt Type OnType DOT JavaIdentifier LPAREN");
+ consumeInterTypeMethodHeaderName();
+ break ;
+
+ case 162 : // System.out.println("AbstractInterTypeMethodDeclaration ::= InterTypeMethodHeader SEMICOLON");
+ // set to false to consume a method without body
+ consumeInterTypeMethodDeclaration(false);
+ break ;
+
+ case 163 : // System.out.println("InterTypeConstructorDeclaration ::= InterTypeConstructorHeader ConstructorBody");
+ // set to true to consume a method with a body
+ consumeInterTypeConstructorDeclaration();
+ break ;
+
+ case 164 : // System.out.println("InterTypeConstructorHeader ::= InterTypeConstructorHeaderName...");
+ consumeInterTypeConstructorHeader();
+ break ;
+
+ case 165 : // System.out.println("InterTypeConstructorHeaderName ::= Modifiersopt Name DOT new LPAREN");
+ consumeInterTypeConstructorHeaderName();
+ break ;
+
+ case 166 : // System.out.println("InterTypeFieldDeclaration ::= Modifiersopt Type OnType DOT JavaIdentifier...");
+ consumeInterTypeFieldDeclaration();
+ break ;
+
+ case 170 : // System.out.println("DeclareDeclaration ::= DeclareHeader PseudoTokens SEMICOLON");
+ consumeDeclareDeclaration();
+ break ;
+
+ case 171 : // System.out.println("DeclareHeader ::= declare Identifier COLON");
+ consumeDeclareHeader();
+ break ;
+
+ case 173 : // System.out.println("PseudoTokens ::= PseudoTokens PseudoToken");
+ consumePseudoTokens();
+ break ;
+
+ case 174 : // System.out.println("PseudoToken ::= JavaIdentifier");
+ consumePseudoTokenIdentifier();
+ break ;
+
+ case 175 : // System.out.println("PseudoToken ::= LPAREN");
+ consumePseudoToken("(");
+ break ;
+
+ case 176 : // System.out.println("PseudoToken ::= RPAREN");
+ consumePseudoToken(")");
+ break ;
+
+ case 177 : // System.out.println("PseudoToken ::= DOT");
+ consumePseudoToken(".");
+ break ;
+
+ case 178 : // System.out.println("PseudoToken ::= MULTIPLY");
+ consumePseudoToken("*");
+ break ;
+
+ case 179 : // System.out.println("PseudoToken ::= PLUS");
+ consumePseudoToken("+");
+ break ;
+
+ case 180 : // System.out.println("PseudoToken ::= AND_AND");
+ consumePseudoToken("&&");
+ break ;
+
+ case 181 : // System.out.println("PseudoToken ::= OR_OR");
+ consumePseudoToken("||");
+ break ;
+
+ case 182 : // System.out.println("PseudoToken ::= NOT");
+ consumePseudoToken("!");
+ break ;
+
+ case 183 : // System.out.println("PseudoToken ::= COLON");
+ consumePseudoToken(":");
+ break ;
+
+ case 184 : // System.out.println("PseudoToken ::= COMMA");
+ consumePseudoToken(",");
+ break ;
+
+ case 185 : // System.out.println("PseudoToken ::= LBRACKET");
+ consumePseudoToken("[");
+ break ;
+
+ case 186 : // System.out.println("PseudoToken ::= RBRACKET");
+ consumePseudoToken("]");
+ break ;
+
+ case 187 : // System.out.println("PseudoToken ::= PrimitiveType");
+ consumePseudoTokenPrimitiveType();
+ break ;
+
+ case 188 : // System.out.println("PseudoToken ::= Modifier");
+ consumePseudoTokenModifier();
+ break ;
+
+ case 189 : // System.out.println("PseudoToken ::= Literal");
+ consumePseudoTokenLiteral();
+ break ;
+
+ case 190 : // System.out.println("PseudoToken ::= this");
+ consumePseudoToken("this", 1, true);
+ break ;
+
+ case 191 : // System.out.println("PseudoToken ::= super");
+ consumePseudoToken("super", 1, true);
+ break ;
+
+ case 192 : // System.out.println("PseudoToken ::= if LPAREN Expression RPAREN");
+ consumePseudoTokenIf();
+ break ;
+
+ case 193 : // System.out.println("PseudoToken ::= assert");
+ consumePseudoToken("assert", 1, true);
+ break ;
+
+ case 194 : // System.out.println("PseudoToken ::= import");
+ consumePseudoToken("import", 1, true);
+ break ;
+
+ case 195 : // System.out.println("PseudoToken ::= package");
+ consumePseudoToken("package", 1, true);
+ break ;
+
+ case 196 : // System.out.println("PseudoToken ::= throw");
+ consumePseudoToken("throw", 1, true);
+ break ;
+
+ case 197 : // System.out.println("PseudoToken ::= new");
+ consumePseudoToken("new", 1, true);
+ break ;
+
+ case 198 : // System.out.println("PseudoToken ::= do");
+ consumePseudoToken("do", 1, true);
+ break ;
+
+ case 199 : // System.out.println("PseudoToken ::= for");
+ consumePseudoToken("for", 1, true);
+ break ;
+
+ case 200 : // System.out.println("PseudoToken ::= switch");
+ consumePseudoToken("switch", 1, true);
+ break ;
+
+ case 201 : // System.out.println("PseudoToken ::= try");
+ consumePseudoToken("try", 1, true);
+ break ;
+
+ case 202 : // System.out.println("PseudoToken ::= while");
+ consumePseudoToken("while", 1, true);
+ break ;
+
+ case 203 : // System.out.println("PseudoToken ::= break");
+ consumePseudoToken("break", 1, true);
+ break ;
+
+ case 204 : // System.out.println("PseudoToken ::= continue");
+ consumePseudoToken("continue", 1, true);
+ break ;
+
+ case 205 : // System.out.println("PseudoToken ::= return");
+ consumePseudoToken("return", 1, true);
+ break ;
+
+ case 206 : // System.out.println("PseudoToken ::= case");
+ consumePseudoToken("case", 1, true);
+ break ;
+
+ case 207 : // System.out.println("PseudoToken ::= catch");
+ consumePseudoToken("catch", 0, true);
+ break ;
+
+ case 208 : // System.out.println("PseudoToken ::= instanceof");
+ consumePseudoToken("instanceof", 0, true);
+ break ;
+
+ case 209 : // System.out.println("PseudoToken ::= else");
+ consumePseudoToken("else", 0, true);
+ break ;
+
+ case 210 : // System.out.println("PseudoToken ::= extends");
+ consumePseudoToken("extends", 0, true);
+ break ;
+
+ case 211 : // System.out.println("PseudoToken ::= finally");
+ consumePseudoToken("finally", 0, true);
+ break ;
+
+ case 212 : // System.out.println("PseudoToken ::= implements");
+ consumePseudoToken("implements", 0, true);
+ break ;
+
+ case 213 : // System.out.println("PseudoToken ::= throws");
+ consumePseudoToken("throws", 0, true);
+ break ;
+
+ case 214 : // System.out.println("ClassDeclaration ::= ClassHeader ClassBody");
+ consumeClassDeclaration();
+ break ;
+
+ case 215 : // System.out.println("ClassHeader ::= ClassHeaderName ClassHeaderExtendsopt ClassHeaderImplementsopt");
+ consumeClassHeader();
+ break ;
+
+ case 216 : // System.out.println("ClassHeaderName ::= Modifiersopt class JavaIdentifier");
+ consumeClassHeaderName();
+ break ;
+
+ case 217 : // System.out.println("ClassHeaderExtends ::= extends ClassType");
+ consumeClassHeaderExtends();
+ break ;
+
+ case 218 : // System.out.println("ClassHeaderImplements ::= implements InterfaceTypeList");
+ consumeClassHeaderImplements();
+ break ;
+
+ case 220 : // System.out.println("InterfaceTypeList ::= InterfaceTypeList COMMA InterfaceType");
+ consumeInterfaceTypeList();
+ break ;
+
+ case 221 : // System.out.println("InterfaceType ::= ClassOrInterfaceType");
+ consumeInterfaceType();
+ break ;
+
+ case 224 : // System.out.println("ClassBodyDeclarations ::= ClassBodyDeclarations ClassBodyDeclaration");
+ consumeClassBodyDeclarations();
+ break ;
+
+ case 228 : // System.out.println("ClassBodyDeclaration ::= Diet NestedMethod Block");
+ consumeClassBodyDeclaration();
+ break ;
+
+ case 229 : // System.out.println("Diet ::=");
+ consumeDiet();
+ break ;
+
+ case 230 : // System.out.println("Initializer ::= Diet NestedMethod Block");
+ consumeClassBodyDeclaration();
+ break ;
+
+ case 237 : // System.out.println("ClassMemberDeclaration ::= SEMICOLON");
+ consumeEmptyClassMemberDeclaration();
+ break ;
+
+ case 238 : // System.out.println("FieldDeclaration ::= Modifiersopt Type VariableDeclarators SEMICOLON");
+ consumeFieldDeclaration();
+ break ;
+
+ case 240 : // System.out.println("VariableDeclarators ::= VariableDeclarators COMMA VariableDeclarator");
+ consumeVariableDeclarators();
+ break ;
+
+ case 243 : // System.out.println("EnterVariable ::=");
+ consumeEnterVariable();
+ break ;
+
+ case 244 : // System.out.println("ExitVariableWithInitialization ::=");
+ consumeExitVariableWithInitialization();
+ break ;
+
+ case 245 : // System.out.println("ExitVariableWithoutInitialization ::=");
+ consumeExitVariableWithoutInitialization();
+ break ;
+
+ case 246 : // System.out.println("ForceNoDiet ::=");
+ consumeForceNoDiet();
+ break ;
+
+ case 247 : // System.out.println("RestoreDiet ::=");
+ consumeRestoreDiet();
+ break ;
+
+ case 252 : // System.out.println("MethodDeclaration ::= MethodHeader MethodBody");
+ // set to true to consume a method with a body
+ consumeMethodDeclaration(true);
+ break ;
+
+ case 253 : // System.out.println("AbstractMethodDeclaration ::= MethodHeader SEMICOLON");
+ // set to false to consume a method without body
+ consumeMethodDeclaration(false);
+ break ;
+
+ case 254 : // System.out.println("MethodHeader ::= MethodHeaderName MethodHeaderParameters MethodHeaderExtendedDims");
+ consumeMethodHeader();
+ break ;
+
+ case 255 : // System.out.println("MethodPushModifiersHeader ::= MethodPushModifiersHeaderName MethodHeaderParameters");
+ consumeMethodHeader();
+ break ;
+
+ case 256 : // System.out.println("MethodPushModifiersHeaderName ::= Modifiers Type PushModifiers...");
+ consumeMethodPushModifiersHeaderName();
+ break ;
+
+ case 257 : // System.out.println("MethodPushModifiersHeaderName ::= Type PushModifiers JavaIdentifierNoAround LPAREN");
+ consumeMethodPushModifiersHeaderName();
+ break ;
+
+ case 258 : // System.out.println("MethodHeaderName ::= Modifiersopt Type JavaIdentifierNoAround LPAREN");
+ consumeMethodHeaderName();
+ break ;
+
+ case 259 : // System.out.println("MethodHeaderParameters ::= FormalParameterListopt RPAREN");
+ consumeMethodHeaderParameters();
+ break ;
+
+ case 260 : // System.out.println("MethodHeaderExtendedDims ::= Dimsopt");
+ consumeMethodHeaderExtendedDims();
+ break ;
+
+ case 261 : // System.out.println("MethodHeaderThrowsClause ::= throws ClassTypeList");
+ consumeMethodHeaderThrowsClause();
+ break ;
+
+ case 262 : // System.out.println("ConstructorHeader ::= ConstructorHeaderName MethodHeaderParameters...");
+ consumeConstructorHeader();
+ break ;
+
+ case 263 : // System.out.println("ConstructorHeaderName ::= Modifiersopt Identifier LPAREN");
+ consumeConstructorHeaderName();
+ break ;
+
+ case 264 : // System.out.println("ConstructorHeaderName ::= Modifiersopt aspect LPAREN");
+ consumeConstructorHeaderName();
+ break ;
+
+ case 266 : // System.out.println("FormalParameterList ::= FormalParameterList COMMA FormalParameter");
+ consumeFormalParameterList();
+ break ;
+
+ case 267 : // System.out.println("FormalParameter ::= Modifiersopt Type VariableDeclaratorId");
+ // the boolean is used to know if the modifiers should be reset
+ consumeFormalParameter();
+ break ;
+
+ case 269 : // System.out.println("ClassTypeList ::= ClassTypeList COMMA ClassTypeElt");
+ consumeClassTypeList();
+ break ;
+
+ case 270 : // System.out.println("ClassTypeElt ::= ClassType");
+ consumeClassTypeElt();
+ break ;
+
+ case 271 : // System.out.println("MethodBody ::= NestedMethod LBRACE BlockStatementsopt RBRACE");
+ consumeMethodBody();
+ break ;
+
+ case 272 : // System.out.println("NestedMethod ::=");
+ consumeNestedMethod();
+ break ;
+
+ case 273 : // System.out.println("StaticInitializer ::= StaticOnly Block");
+ consumeStaticInitializer();
+ break ;
+
+ case 274 : // System.out.println("StaticOnly ::= static");
+ consumeStaticOnly();
+ break ;
+
+ case 275 : // System.out.println("ConstructorDeclaration ::= ConstructorHeader ConstructorBody");
+ consumeConstructorDeclaration() ;
+ break ;
+
+ case 276 : // System.out.println("ConstructorDeclaration ::= ConstructorHeader SEMICOLON");
+ consumeInvalidConstructorDeclaration() ;
+ break ;
+
+ case 277 : // System.out.println("ConstructorBody ::= NestedMethod LBRACE ConstructorBlockStatementsopt RBRACE");
+ consumeConstructorBody();
+ break ;
+
+ case 280 : // System.out.println("ConstructorBlockStatementsopt ::= ExplicitConstructorInvocation BlockStatements");
+ consumeConstructorBlockStatements();
+ break ;
+
+ case 281 : // System.out.println("ExplicitConstructorInvocation ::= this LPAREN ArgumentListopt RPAREN SEMICOLON");
+ consumeExplicitConstructorInvocation(0,ExplicitConstructorCall.This);
+ break ;
+
+ case 282 : // System.out.println("ExplicitConstructorInvocation ::= super LPAREN ArgumentListopt RPAREN SEMICOLON");
+ consumeExplicitConstructorInvocation(0,ExplicitConstructorCall.Super);
+ break ;
+
+ case 283 : // System.out.println("ExplicitConstructorInvocation ::= Primary DOT super LPAREN ArgumentListopt RPAREN");
+ consumeExplicitConstructorInvocation(1, ExplicitConstructorCall.Super);
+ break ;
+
+ case 284 : // System.out.println("ExplicitConstructorInvocation ::= Name DOT super LPAREN ArgumentListopt RPAREN...");
+ consumeExplicitConstructorInvocation(2, ExplicitConstructorCall.Super);
+ break ;
+
+ case 285 : // System.out.println("ExplicitConstructorInvocation ::= Primary DOT this LPAREN ArgumentListopt RPAREN...");
+ consumeExplicitConstructorInvocation(1, ExplicitConstructorCall.This);
+ break ;
+
+ case 286 : // System.out.println("ExplicitConstructorInvocation ::= Name DOT this LPAREN ArgumentListopt RPAREN...");
+ consumeExplicitConstructorInvocation(2, ExplicitConstructorCall.This);
+ break ;
+
+ case 287 : // System.out.println("InterfaceDeclaration ::= InterfaceHeader InterfaceBody");
+ consumeInterfaceDeclaration();
+ break ;
+
+ case 288 : // System.out.println("InterfaceHeader ::= InterfaceHeaderName InterfaceHeaderExtendsopt");
+ consumeInterfaceHeader();
+ break ;
+
+ case 289 : // System.out.println("InterfaceHeaderName ::= Modifiersopt interface JavaIdentifier");
+ consumeInterfaceHeaderName();
+ break ;
+
+ case 291 : // System.out.println("InterfaceHeaderExtends ::= extends InterfaceTypeList");
+ consumeInterfaceHeaderExtends();
+ break ;
+
+ case 294 : // System.out.println("InterfaceMemberDeclarations ::= InterfaceMemberDeclarations...");
+ consumeInterfaceMemberDeclarations();
+ break ;
+
+ case 295 : // System.out.println("InterfaceMemberDeclaration ::= SEMICOLON");
+ consumeEmptyInterfaceMemberDeclaration();
+ break ;
+
+ case 298 : // System.out.println("InterfaceMemberDeclaration ::= InvalidMethodDeclaration");
+ ignoreMethodBody();
+ break ;
+
+ case 299 : // System.out.println("InvalidConstructorDeclaration ::= ConstructorHeader ConstructorBody");
+ ignoreInvalidConstructorDeclaration(true);
+ break ;
+
+ case 300 : // System.out.println("InvalidConstructorDeclaration ::= ConstructorHeader SEMICOLON");
+ ignoreInvalidConstructorDeclaration(false);
+ break ;
+
+ case 306 : // System.out.println("ArrayInitializer ::= LBRACE ,opt RBRACE");
+ consumeEmptyArrayInitializer();
+ break ;
+
+ case 307 : // System.out.println("ArrayInitializer ::= LBRACE VariableInitializers RBRACE");
+ consumeArrayInitializer();
+ break ;
+
+ case 308 : // System.out.println("ArrayInitializer ::= LBRACE VariableInitializers COMMA RBRACE");
+ consumeArrayInitializer();
+ break ;
+
+ case 310 : // System.out.println("VariableInitializers ::= VariableInitializers COMMA VariableInitializer");
+ consumeVariableInitializers();
+ break ;
+
+ case 311 : // System.out.println("Block ::= OpenBlock LBRACE BlockStatementsopt RBRACE");
+ consumeBlock();
+ break ;
+
+ case 312 : // System.out.println("OpenBlock ::=");
+ consumeOpenBlock() ;
+ break ;
+
+ case 314 : // System.out.println("BlockStatements ::= BlockStatements BlockStatement");
+ consumeBlockStatements() ;
+ break ;
+
+ case 318 : // System.out.println("BlockStatement ::= InvalidInterfaceDeclaration");
+ ignoreInterfaceDeclaration();
+ break ;
+
+ case 319 : // System.out.println("LocalVariableDeclarationStatement ::= LocalVariableDeclaration SEMICOLON");
+ consumeLocalVariableDeclarationStatement();
+ break ;
+
+ case 320 : // System.out.println("LocalVariableDeclaration ::= Type PushModifiers VariableDeclarators");
+ consumeLocalVariableDeclaration();
+ break ;
+
+ case 321 : // System.out.println("LocalVariableDeclaration ::= Modifiers Type PushModifiers VariableDeclarators");
+ consumeLocalVariableDeclaration();
+ break ;
+
+ case 322 : // System.out.println("PushModifiers ::=");
+ consumePushModifiers();
+ break ;
+
+ case 346 : // System.out.println("EmptyStatement ::= SEMICOLON");
+ consumeEmptyStatement();
+ break ;
+
+ case 347 : // System.out.println("LabeledStatement ::= JavaIdentifier COLON Statement");
+ consumeStatementLabel() ;
+ break ;
+
+ case 348 : // System.out.println("LabeledStatementNoShortIf ::= JavaIdentifier COLON StatementNoShortIf");
+ consumeStatementLabel() ;
+ break ;
+
+ case 349 : // System.out.println("ExpressionStatement ::= StatementExpression SEMICOLON");
+ consumeExpressionStatement();
+ break ;
+
+ case 357 : // System.out.println("IfThenStatement ::= if LPAREN Expression RPAREN Statement");
+ consumeStatementIfNoElse();
+ break ;
+
+ case 358 : // System.out.println("IfThenElseStatement ::= if LPAREN Expression RPAREN StatementNoShortIf else...");
+ consumeStatementIfWithElse();
+ break ;
+
+ case 359 : // System.out.println("IfThenElseStatementNoShortIf ::= if LPAREN Expression RPAREN StatementNoShortIf...");
+ consumeStatementIfWithElse();
+ break ;
+
+ case 360 : // System.out.println("SwitchStatement ::= switch OpenBlock LPAREN Expression RPAREN SwitchBlock");
+ consumeStatementSwitch() ;
+ break ;
+
+ case 361 : // System.out.println("SwitchBlock ::= LBRACE RBRACE");
+ consumeEmptySwitchBlock() ;
+ break ;
+
+ case 364 : // System.out.println("SwitchBlock ::= LBRACE SwitchBlockStatements SwitchLabels RBRACE");
+ consumeSwitchBlock() ;
+ break ;
+
+ case 366 : // System.out.println("SwitchBlockStatements ::= SwitchBlockStatements SwitchBlockStatement");
+ consumeSwitchBlockStatements() ;
+ break ;
+
+ case 367 : // System.out.println("SwitchBlockStatement ::= SwitchLabels BlockStatements");
+ consumeSwitchBlockStatement() ;
+ break ;
+
+ case 369 : // System.out.println("SwitchLabels ::= SwitchLabels SwitchLabel");
+ consumeSwitchLabels() ;
+ break ;
+
+ case 370 : // System.out.println("SwitchLabel ::= case ConstantExpression COLON");
+ consumeCaseLabel();
+ break ;
+
+ case 371 : // System.out.println("SwitchLabel ::= default COLON");
+ consumeDefaultLabel();
+ break ;
+
+ case 372 : // System.out.println("WhileStatement ::= while LPAREN Expression RPAREN Statement");
+ consumeStatementWhile() ;
+ break ;
+
+ case 373 : // System.out.println("WhileStatementNoShortIf ::= while LPAREN Expression RPAREN StatementNoShortIf");
+ consumeStatementWhile() ;
+ break ;
+
+ case 374 : // System.out.println("DoStatement ::= do Statement while LPAREN Expression RPAREN SEMICOLON");
+ consumeStatementDo() ;
+ break ;
+
+ case 375 : // System.out.println("ForStatement ::= for LPAREN ForInitopt SEMICOLON Expressionopt SEMICOLON...");
+ consumeStatementFor() ;
+ break ;
+
+ case 376 : // System.out.println("ForStatementNoShortIf ::= for LPAREN ForInitopt SEMICOLON Expressionopt SEMICOLON");
+ consumeStatementFor() ;
+ break ;
+
+ case 377 : // System.out.println("ForInit ::= StatementExpressionList");
+ consumeForInit() ;
+ break ;
+
+ case 381 : // System.out.println("StatementExpressionList ::= StatementExpressionList COMMA StatementExpression");
+ consumeStatementExpressionList() ;
+ break ;
+
+ case 382 : // System.out.println("AssertStatement ::= assert Expression SEMICOLON");
+ consumeSimpleAssertStatement() ;
+ break ;
+
+ case 383 : // System.out.println("AssertStatement ::= assert Expression COLON Expression SEMICOLON");
+ consumeAssertStatement() ;
+ break ;
+
+ case 384 : // System.out.println("BreakStatement ::= break SEMICOLON");
+ consumeStatementBreak() ;
+ break ;
+
+ case 385 : // System.out.println("BreakStatement ::= break Identifier SEMICOLON");
+ consumeStatementBreakWithLabel() ;
+ break ;
+
+ case 386 : // System.out.println("ContinueStatement ::= continue SEMICOLON");
+ consumeStatementContinue() ;
+ break ;
+
+ case 387 : // System.out.println("ContinueStatement ::= continue Identifier SEMICOLON");
+ consumeStatementContinueWithLabel() ;
+ break ;
+
+ case 388 : // System.out.println("ReturnStatement ::= return Expressionopt SEMICOLON");
+ consumeStatementReturn() ;
+ break ;
+
+ case 389 : // System.out.println("ThrowStatement ::= throw Expression SEMICOLON");
+ consumeStatementThrow();
+
+ break ;
+
+ case 390 : // System.out.println("SynchronizedStatement ::= OnlySynchronized LPAREN Expression RPAREN Block");
+ consumeStatementSynchronized();
+ break ;
+
+ case 391 : // System.out.println("OnlySynchronized ::= synchronized");
+ consumeOnlySynchronized();
+ break ;
+
+ case 392 : // System.out.println("TryStatement ::= try Block Catches");
+ consumeStatementTry(false);
+ break ;
+
+ case 393 : // System.out.println("TryStatement ::= try Block Catchesopt Finally");
+ consumeStatementTry(true);
+ break ;
+
+ case 395 : // System.out.println("Catches ::= Catches CatchClause");
+ consumeCatches();
+ break ;
+
+ case 396 : // System.out.println("CatchClause ::= catch LPAREN FormalParameter RPAREN Block");
+ consumeStatementCatch() ;
+ break ;
+
+ case 398 : // System.out.println("PushLPAREN ::= LPAREN");
+ consumeLeftParen();
+ break ;
+
+ case 399 : // System.out.println("PushRPAREN ::= RPAREN");
+ consumeRightParen();
+ break ;
+
+ case 403 : // System.out.println("PrimaryNoNewArray ::= this");
+ consumePrimaryNoNewArrayThis();
+ break ;
+
+ case 404 : // System.out.println("PrimaryNoNewArray ::= PushLPAREN Expression PushRPAREN");
+ consumePrimaryNoNewArray();
+ break ;
+
+ case 407 : // System.out.println("PrimaryNoNewArray ::= Name DOT this");
+ consumePrimaryNoNewArrayNameThis();
+ break ;
+
+ case 408 : // System.out.println("PrimaryNoNewArray ::= Name DOT super");
+ consumePrimaryNoNewArrayNameSuper();
+ break ;
+
+ case 409 : // System.out.println("PrimaryNoNewArray ::= Name DOT class");
+ consumePrimaryNoNewArrayName();
+ break ;
+
+ case 410 : // System.out.println("PrimaryNoNewArray ::= ArrayType DOT class");
+ consumePrimaryNoNewArrayArrayType();
+ break ;
+
+ case 411 : // System.out.println("PrimaryNoNewArray ::= PrimitiveType DOT class");
+ consumePrimaryNoNewArrayPrimitiveType();
+ break ;
+
+ case 414 : // System.out.println("AllocationHeader ::= new ClassType LPAREN ArgumentListopt RPAREN");
+ consumeAllocationHeader();
+ break ;
+
+ case 415 : // System.out.println("ClassInstanceCreationExpression ::= new ClassType LPAREN ArgumentListopt RPAREN...");
+ consumeClassInstanceCreationExpression();
+ break ;
+
+ case 416 : // System.out.println("ClassInstanceCreationExpression ::= Primary DOT new SimpleName LPAREN...");
+ consumeClassInstanceCreationExpressionQualified() ;
+ break ;
+
+ case 417 : // System.out.println("ClassInstanceCreationExpression ::= ClassInstanceCreationExpressionName new...");
+ consumeClassInstanceCreationExpressionQualified() ;
+ break ;
+
+ case 418 : // System.out.println("ClassInstanceCreationExpressionName ::= Name DOT");
+ consumeClassInstanceCreationExpressionName() ;
+ break ;
+
+ case 419 : // System.out.println("ClassBodyopt ::=");
+ consumeClassBodyopt();
+ break ;
+
+ case 421 : // System.out.println("EnterAnonymousClassBody ::=");
+ consumeEnterAnonymousClassBody();
+ break ;
+
+ case 423 : // System.out.println("ArgumentList ::= ArgumentList COMMA Expression");
+ consumeArgumentList();
+ break ;
+
+ case 424 : // System.out.println("ArrayCreationExpression ::= new PrimitiveType DimWithOrWithOutExprs...");
+ consumeArrayCreationExpression();
+ break ;
+
+ case 425 : // System.out.println("ArrayCreationExpression ::= new ClassOrInterfaceType DimWithOrWithOutExprs...");
+ consumeArrayCreationExpression();
+ break ;
+
+ case 427 : // System.out.println("DimWithOrWithOutExprs ::= DimWithOrWithOutExprs DimWithOrWithOutExpr");
+ consumeDimWithOrWithOutExprs();
+ break ;
+
+ case 429 : // System.out.println("DimWithOrWithOutExpr ::= LBRACKET RBRACKET");
+ consumeDimWithOrWithOutExpr();
+ break ;
+
+ case 430 : // System.out.println("Dims ::= DimsLoop");
+ consumeDims();
+ break ;
+
+ case 433 : // System.out.println("OneDimLoop ::= LBRACKET RBRACKET");
+ consumeOneDimLoop();
+ break ;
+
+ case 434 : // System.out.println("FieldAccess ::= Primary DOT JavaIdentifier");
+ consumeFieldAccess(false);
+ break ;
+
+ case 435 : // System.out.println("FieldAccess ::= super DOT JavaIdentifier");
+ consumeFieldAccess(true);
+ break ;
+
+ case 436 : // System.out.println("MethodInvocation ::= NameOrAj LPAREN ArgumentListopt RPAREN");
+ consumeMethodInvocationName();
+ break ;
+
+ case 437 : // System.out.println("MethodInvocation ::= Primary DOT JavaIdentifier LPAREN ArgumentListopt RPAREN");
+ consumeMethodInvocationPrimary();
+ break ;
+
+ case 438 : // System.out.println("MethodInvocation ::= super DOT JavaIdentifier LPAREN ArgumentListopt RPAREN");
+ consumeMethodInvocationSuper();
+ break ;
+
+ case 439 : // System.out.println("ArrayAccess ::= Name LBRACKET Expression RBRACKET");
+ consumeArrayAccess(true);
+ break ;
+
+ case 440 : // System.out.println("ArrayAccess ::= PrimaryNoNewArray LBRACKET Expression RBRACKET");
+ consumeArrayAccess(false);
+ break ;
+
+ case 442 : // System.out.println("PostfixExpression ::= NameOrAj");
+ consumePostfixExpression();
+ break ;
+
+ case 445 : // System.out.println("PostIncrementExpression ::= PostfixExpression PLUS_PLUS");
+ consumeUnaryExpression(OperatorExpression.PLUS,true);
+ break ;
+
+ case 446 : // System.out.println("PostDecrementExpression ::= PostfixExpression MINUS_MINUS");
+ consumeUnaryExpression(OperatorExpression.MINUS,true);
+ break ;
+
+ case 447 : // System.out.println("PushPosition ::=");
+ consumePushPosition();
+ break ;
+
+ case 450 : // System.out.println("UnaryExpression ::= PLUS PushPosition UnaryExpression");
+ consumeUnaryExpression(OperatorExpression.PLUS);
+ break ;
+
+ case 451 : // System.out.println("UnaryExpression ::= MINUS PushPosition UnaryExpression");
+ consumeUnaryExpression(OperatorExpression.MINUS);
+ break ;
+
+ case 453 : // System.out.println("PreIncrementExpression ::= PLUS_PLUS PushPosition UnaryExpression");
+ consumeUnaryExpression(OperatorExpression.PLUS,false);
+ break ;
+
+ case 454 : // System.out.println("PreDecrementExpression ::= MINUS_MINUS PushPosition UnaryExpression");
+ consumeUnaryExpression(OperatorExpression.MINUS,false);
+ break ;
+
+ case 456 : // System.out.println("UnaryExpressionNotPlusMinus ::= TWIDDLE PushPosition UnaryExpression");
+ consumeUnaryExpression(OperatorExpression.TWIDDLE);
+ break ;
+
+ case 457 : // System.out.println("UnaryExpressionNotPlusMinus ::= NOT PushPosition UnaryExpression");
+ consumeUnaryExpression(OperatorExpression.NOT);
+ break ;
+
+ case 459 : // System.out.println("CastExpression ::= PushLPAREN PrimitiveType Dimsopt PushRPAREN UnaryExpression");
+ consumeCastExpression();
+ break ;
+
+ case 460 : // System.out.println("CastExpression ::= PushLPAREN Name Dims PushRPAREN UnaryExpressionNotPlusMinus");
+ consumeCastExpression();
+ break ;
+
+ case 461 : // System.out.println("CastExpression ::= PushLPAREN Expression PushRPAREN UnaryExpressionNotPlusMinus");
+ consumeCastExpressionLL1();
+ break ;
+
+ case 463 : // System.out.println("MultiplicativeExpression ::= MultiplicativeExpression MULTIPLY UnaryExpression");
+ consumeBinaryExpression(OperatorExpression.MULTIPLY);
+ break ;
+
+ case 464 : // System.out.println("MultiplicativeExpression ::= MultiplicativeExpression DIVIDE UnaryExpression");
+ consumeBinaryExpression(OperatorExpression.DIVIDE);
+ break ;
+
+ case 465 : // System.out.println("MultiplicativeExpression ::= MultiplicativeExpression REMAINDER UnaryExpression");
+ consumeBinaryExpression(OperatorExpression.REMAINDER);
+ break ;
+
+ case 467 : // System.out.println("AdditiveExpression ::= AdditiveExpression PLUS MultiplicativeExpression");
+ consumeBinaryExpression(OperatorExpression.PLUS);
+ break ;
+
+ case 468 : // System.out.println("AdditiveExpression ::= AdditiveExpression MINUS MultiplicativeExpression");
+ consumeBinaryExpression(OperatorExpression.MINUS);
+ break ;
+
+ case 470 : // System.out.println("ShiftExpression ::= ShiftExpression LEFT_SHIFT AdditiveExpression");
+ consumeBinaryExpression(OperatorExpression.LEFT_SHIFT);
+ break ;
+
+ case 471 : // System.out.println("ShiftExpression ::= ShiftExpression RIGHT_SHIFT AdditiveExpression");
+ consumeBinaryExpression(OperatorExpression.RIGHT_SHIFT);
+ break ;
+
+ case 472 : // System.out.println("ShiftExpression ::= ShiftExpression UNSIGNED_RIGHT_SHIFT AdditiveExpression");
+ consumeBinaryExpression(OperatorExpression.UNSIGNED_RIGHT_SHIFT);
+ break ;
+
+ case 474 : // System.out.println("RelationalExpression ::= RelationalExpression LESS ShiftExpression");
+ consumeBinaryExpression(OperatorExpression.LESS);
+ break ;
+
+ case 475 : // System.out.println("RelationalExpression ::= RelationalExpression GREATER ShiftExpression");
+ consumeBinaryExpression(OperatorExpression.GREATER);
+ break ;
+
+ case 476 : // System.out.println("RelationalExpression ::= RelationalExpression LESS_EQUAL ShiftExpression");
+ consumeBinaryExpression(OperatorExpression.LESS_EQUAL);
+ break ;
+
+ case 477 : // System.out.println("RelationalExpression ::= RelationalExpression GREATER_EQUAL ShiftExpression");
+ consumeBinaryExpression(OperatorExpression.GREATER_EQUAL);
+ break ;
+
+ case 478 : // System.out.println("RelationalExpression ::= RelationalExpression instanceof ReferenceType");
+ consumeInstanceOfExpression(OperatorExpression.INSTANCEOF);
+ break ;
+
+ case 480 : // System.out.println("EqualityExpression ::= EqualityExpression EQUAL_EQUAL RelationalExpression");
+ consumeEqualityExpression(OperatorExpression.EQUAL_EQUAL);
+ break ;
+
+ case 481 : // System.out.println("EqualityExpression ::= EqualityExpression NOT_EQUAL RelationalExpression");
+ consumeEqualityExpression(OperatorExpression.NOT_EQUAL);
+ break ;
+
+ case 483 : // System.out.println("AndExpression ::= AndExpression AND EqualityExpression");
+ consumeBinaryExpression(OperatorExpression.AND);
+ break ;
+
+ case 485 : // System.out.println("ExclusiveOrExpression ::= ExclusiveOrExpression XOR AndExpression");
+ consumeBinaryExpression(OperatorExpression.XOR);
+ break ;
+
+ case 487 : // System.out.println("InclusiveOrExpression ::= InclusiveOrExpression OR ExclusiveOrExpression");
+ consumeBinaryExpression(OperatorExpression.OR);
+ break ;
+
+ case 489 : // System.out.println("ConditionalAndExpression ::= ConditionalAndExpression AND_AND InclusiveOrExpression");
+ consumeBinaryExpression(OperatorExpression.AND_AND);
+ break ;
+
+ case 491 : // System.out.println("ConditionalOrExpression ::= ConditionalOrExpression OR_OR ConditionalAndExpression");
+ consumeBinaryExpression(OperatorExpression.OR_OR);
+ break ;
+
+ case 493 : // System.out.println("ConditionalExpression ::= ConditionalOrExpression QUESTION Expression COLON...");
+ consumeConditionalExpression(OperatorExpression.QUESTIONCOLON) ;
+ break ;
+
+ case 496 : // System.out.println("Assignment ::= LeftHandSide AssignmentOperator AssignmentExpression");
+ consumeAssignment();
+ break ;
+
+ case 498 : // System.out.println("Assignment ::= InvalidArrayInitializerAssignement");
+ ignoreExpressionAssignment();
+ break ;
+
+ case 499 : // System.out.println("LeftHandSide ::= NameOrAj");
+ consumeLeftHandSide();
+ break ;
+
+ case 502 : // System.out.println("AssignmentOperator ::= EQUAL");
+ consumeAssignmentOperator(EQUAL);
+ break ;
+
+ case 503 : // System.out.println("AssignmentOperator ::= MULTIPLY_EQUAL");
+ consumeAssignmentOperator(MULTIPLY);
+ break ;
+
+ case 504 : // System.out.println("AssignmentOperator ::= DIVIDE_EQUAL");
+ consumeAssignmentOperator(DIVIDE);
+ break ;
+
+ case 505 : // System.out.println("AssignmentOperator ::= REMAINDER_EQUAL");
+ consumeAssignmentOperator(REMAINDER);
+ break ;
+
+ case 506 : // System.out.println("AssignmentOperator ::= PLUS_EQUAL");
+ consumeAssignmentOperator(PLUS);
+ break ;
+
+ case 507 : // System.out.println("AssignmentOperator ::= MINUS_EQUAL");
+ consumeAssignmentOperator(MINUS);
+ break ;
+
+ case 508 : // System.out.println("AssignmentOperator ::= LEFT_SHIFT_EQUAL");
+ consumeAssignmentOperator(LEFT_SHIFT);
+ break ;
+
+ case 509 : // System.out.println("AssignmentOperator ::= RIGHT_SHIFT_EQUAL");
+ consumeAssignmentOperator(RIGHT_SHIFT);
+ break ;
+
+ case 510 : // System.out.println("AssignmentOperator ::= UNSIGNED_RIGHT_SHIFT_EQUAL");
+ consumeAssignmentOperator(UNSIGNED_RIGHT_SHIFT);
+ break ;
+
+ case 511 : // System.out.println("AssignmentOperator ::= AND_EQUAL");
+ consumeAssignmentOperator(AND);
+ break ;
+
+ case 512 : // System.out.println("AssignmentOperator ::= XOR_EQUAL");
+ consumeAssignmentOperator(XOR);
+ break ;
+
+ case 513 : // System.out.println("AssignmentOperator ::= OR_EQUAL");
+ consumeAssignmentOperator(OR);
+ break ;
+
+ case 520 : // System.out.println("Expressionopt ::=");
+ consumeEmptyExpression();
+ break ;
+
+ case 524 : // System.out.println("ImportDeclarationsopt ::=");
+ consumeEmptyImportDeclarationsopt();
+ break ;
+
+ case 525 : // System.out.println("ImportDeclarationsopt ::= ImportDeclarations");
+ consumeImportDeclarationsopt();
+ break ;
+
+ case 526 : // System.out.println("TypeDeclarationsopt ::=");
+ consumeEmptyTypeDeclarationsopt();
+ break ;
+
+ case 527 : // System.out.println("TypeDeclarationsopt ::= TypeDeclarations");
+ consumeTypeDeclarationsopt();
+ break ;
+
+ case 528 : // System.out.println("ClassBodyDeclarationsopt ::=");
+ consumeEmptyClassBodyDeclarationsopt();
+ break ;
+
+ case 529 : // System.out.println("ClassBodyDeclarationsopt ::= NestedType ClassBodyDeclarations");
+ consumeClassBodyDeclarationsopt();
+ break ;
+
+ case 530 : // System.out.println("Modifiersopt ::=");
+ consumeDefaultModifiers();
+ break ;
+
+ case 531 : // System.out.println("Modifiersopt ::= Modifiers");
+ consumeModifiers();
+ break ;
+
+ case 532 : // System.out.println("BlockStatementsopt ::=");
+ consumeEmptyBlockStatementsopt();
+ break ;
+
+ case 534 : // System.out.println("Dimsopt ::=");
+ consumeEmptyDimsopt();
+ break ;
+
+ case 536 : // System.out.println("ArgumentListopt ::=");
+ consumeEmptyArgumentListopt();
+ break ;
+
+ case 540 : // System.out.println("FormalParameterListopt ::=");
+ consumeFormalParameterListopt();
+ break ;
+
+ case 544 : // System.out.println("InterfaceMemberDeclarationsopt ::=");
+ consumeEmptyInterfaceMemberDeclarationsopt();
+ break ;
+
+ case 545 : // System.out.println("InterfaceMemberDeclarationsopt ::= NestedType InterfaceMemberDeclarations");
+ consumeInterfaceMemberDeclarationsopt();
+ break ;
+
+ case 546 : // System.out.println("NestedType ::=");
+ consumeNestedType();
+ break ;
+
+ case 547 : // System.out.println("ForInitopt ::=");
+ consumeEmptyForInitopt();
+ break ;
+
+ case 549 : // System.out.println("ForUpdateopt ::=");
+ consumeEmptyForUpdateopt();
+ break ;
+
+ case 553 : // System.out.println("Catchesopt ::=");
+ consumeEmptyCatchesopt();
+ break ;
+
+ case 555 : // System.out.println("ArrayInitializeropt ::=");
+ consumeEmptyArrayInitializeropt();
+ break ;
+
+ }
+}
+protected void consumeSimpleAssertStatement() {
+ super.consumeSimpleAssertStatement();
+}
+ public AjParser(
+ ProblemReporter problemReporter,
+ boolean optimizeStringLiterals,
+ boolean assertMode) {
+ super(problemReporter, optimizeStringLiterals, assertMode);
+ }
+
+}
diff --git a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/parser/AjScanner.java b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/parser/AjScanner.java
new file mode 100644
index 000000000..879a409bb
--- /dev/null
+++ b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/parser/AjScanner.java
@@ -0,0 +1,74 @@
+/* *******************************************************************
+ * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC).
+ * All rights reserved.
+ * This program and the accompanying materials are made available
+ * under the terms of the Common Public License v1.0
+ * which accompanies this distribution and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * Xerox/PARC initial implementation
+ * ******************************************************************/
+
+
+
+package org.aspectj.ajdt.internal.compiler.parser;
+
+import org.aspectj.ajdt.compiler.IAjTerminalSymbols;
+import org.eclipse.jdt.core.compiler.*;
+import org.eclipse.jdt.internal.compiler.parser.Scanner;
+import org.eclipse.jdt.internal.compiler.util.CharOperation;
+
+
+public class AjScanner extends Scanner implements IScanner {
+ public AjScanner(
+ boolean tokenizeComments,
+ boolean tokenizeWhiteSpace,
+ boolean checkNonExternalizedStringLiterals) {
+ super(
+ tokenizeComments,
+ tokenizeWhiteSpace,
+ checkNonExternalizedStringLiterals);
+ }
+
+ public AjScanner(
+ boolean tokenizeComments,
+ boolean tokenizeWhiteSpace,
+ boolean checkNonExternalizedStringLiterals,
+ boolean assertMode) {
+ super(
+ tokenizeComments,
+ tokenizeWhiteSpace,
+ checkNonExternalizedStringLiterals,
+ assertMode);
+ }
+
+
+ private static final char[] aspectV = "aspect".toCharArray();
+ private static final char[] pointcutV = "pointcut".toCharArray();
+ private static final char[] privilegedV = "privileged".toCharArray();
+ private static final char[] beforeV = "before".toCharArray();
+ private static final char[] afterV = "after".toCharArray();
+ private static final char[] aroundV = "around".toCharArray();
+ private static final char[] declareV = "declare".toCharArray();
+
+
+
+ public int scanIdentifierOrKeyword() throws InvalidInputException {
+ int kind = super.scanIdentifierOrKeyword();
+ if (kind != IAjTerminalSymbols.TokenNameIdentifier) return kind;
+
+ char[] contents = getCurrentIdentifierSource();
+
+ //XXX performance here is less than optimal, but code simplicity is pretty damn good
+ if (CharOperation.equals(aspectV, contents)) return IAjTerminalSymbols.TokenNameaspect;
+ else if (CharOperation.equals(pointcutV, contents)) return IAjTerminalSymbols.TokenNamepointcut;
+ else if (CharOperation.equals(privilegedV, contents)) return IAjTerminalSymbols.TokenNameprivileged;
+ else if (CharOperation.equals(beforeV, contents)) return IAjTerminalSymbols.TokenNamebefore;
+ else if (CharOperation.equals(afterV, contents)) return IAjTerminalSymbols.TokenNameafter;
+ else if (CharOperation.equals(aroundV, contents)) return IAjTerminalSymbols.TokenNamearound;
+ else if (CharOperation.equals(declareV, contents)) return IAjTerminalSymbols.TokenNamedeclare;
+
+ return kind;
+ }
+}
diff --git a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/parser/parser1.rsc b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/parser/parser1.rsc
new file mode 100644
index 000000000..18aee96d3
--- /dev/null
+++ b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/parser/parser1.rsc
Binary files differ
diff --git a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/parser/parser2.rsc b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/parser/parser2.rsc
new file mode 100644
index 000000000..34fc767ed
--- /dev/null
+++ b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/parser/parser2.rsc
Binary files differ
diff --git a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/parser/parser3.rsc b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/parser/parser3.rsc
new file mode 100644
index 000000000..49589a249
--- /dev/null
+++ b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/parser/parser3.rsc
Binary files differ
diff --git a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/parser/parser4.rsc b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/parser/parser4.rsc
new file mode 100644
index 000000000..1394b9c07
--- /dev/null
+++ b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/parser/parser4.rsc
Binary files differ
diff --git a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/parser/parser5.rsc b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/parser/parser5.rsc
new file mode 100644
index 000000000..77cade3a8
--- /dev/null
+++ b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/parser/parser5.rsc
Binary files differ
diff --git a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/problem/AjProblemReporter.java b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/problem/AjProblemReporter.java
new file mode 100644
index 000000000..c76ca4fb3
--- /dev/null
+++ b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/problem/AjProblemReporter.java
@@ -0,0 +1,135 @@
+/* *******************************************************************
+ * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC).
+ * All rights reserved.
+ * This program and the accompanying materials are made available
+ * under the terms of the Common Public License v1.0
+ * which accompanies this distribution and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * Xerox/PARC initial implementation
+ * ******************************************************************/
+
+
+ package org.aspectj.ajdt.internal.compiler.problem;
+
+import java.lang.reflect.Modifier;
+import java.util.Iterator;
+
+import org.aspectj.ajdt.internal.compiler.ast.Proceed;
+import org.aspectj.ajdt.internal.compiler.lookup.EclipseWorld;
+import org.aspectj.util.FuzzyBoolean;
+import org.aspectj.weaver.*;
+import org.aspectj.weaver.Shadow;
+import org.aspectj.weaver.patterns.DeclareSoft;
+import org.eclipse.jdt.internal.compiler.*;
+import org.eclipse.jdt.internal.compiler.ast.AstNode;
+import org.eclipse.jdt.internal.compiler.impl.*;
+import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
+import org.eclipse.jdt.internal.compiler.lookup.*;
+import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
+import org.eclipse.jdt.internal.compiler.problem.ProblemReporter;
+
+public class AjProblemReporter extends ProblemReporter {
+ private static final boolean DUMP_STACK = false;
+
+ public EclipseWorld world;
+
+ public AjProblemReporter(
+ IErrorHandlingPolicy policy,
+ CompilerOptions options,
+ IProblemFactory problemFactory) {
+ super(policy, options, problemFactory);
+ }
+
+
+
+ public void unhandledException(
+ TypeBinding exceptionType,
+ AstNode location)
+ {
+ if (!world.getDeclareSoft().isEmpty()) {
+ Shadow callSite = world.makeShadow(location, referenceContext);
+ if (callSite == null) {
+ super.unhandledException(exceptionType, location);
+ return;
+ }
+ Shadow enclosingExec = world.makeShadow(referenceContext);
+ // System.err.println("about to show error for unhandled exception: " + exceptionType +
+ // " at " + location + " in " + referenceContext);
+
+
+ for (Iterator i = world.getDeclareSoft().iterator(); i.hasNext(); ) {
+ DeclareSoft d = (DeclareSoft)i.next();
+ FuzzyBoolean match = d.getPointcut().match(callSite);
+ if (match.alwaysTrue()) {
+ //System.err.println("matched callSite: " + callSite + " with " + d);
+ return;
+ } else if (!match.alwaysFalse()) {
+ throw new RuntimeException("unimplemented, shouldn't have fuzzy match here");
+ }
+
+ match = d.getPointcut().match(enclosingExec);
+ if (match.alwaysTrue()) {
+ //System.err.println("matched enclosingExec: " + enclosingExec + " with " + d);
+ return;
+ } else if (!match.alwaysFalse()) {
+ throw new RuntimeException("unimplemented, shouldn't have fuzzy match here");
+ }
+ }
+ }
+
+ //??? is this always correct
+ if (location instanceof Proceed) {
+ return;
+ }
+
+ super.unhandledException(exceptionType, location);
+ }
+
+ public void handle(
+ int problemId,
+ String[] problemArguments,
+ int severity,
+ int problemStartPosition,
+ int problemEndPosition,
+ ReferenceContext referenceContext,
+ CompilationResult unitResult) {
+
+ if (severity != Ignore && DUMP_STACK) {
+ Thread.currentThread().dumpStack();
+ }
+ super.handle(
+ problemId,
+ problemArguments,
+ severity,
+ problemStartPosition,
+ problemEndPosition,
+ referenceContext,
+ unitResult);
+ }
+
+
+ public void abstractMethodMustBeImplemented(
+ SourceTypeBinding type,
+ MethodBinding abstractMethod)
+ {
+ // if we implemented this method by an inter-type declaration, then there is no error
+ //??? be sure this is always right
+ ResolvedTypeX onTypeX = world.fromEclipse(type); //abstractMethod.declaringClass);
+ for (Iterator i = onTypeX.getInterTypeMungers().iterator(); i.hasNext(); ) {
+ ConcreteTypeMunger m = (ConcreteTypeMunger)i.next();
+ if (m.matches(onTypeX)) {
+ ResolvedMember sig = m.getSignature();
+ if (Modifier.isPublic(sig.getModifiers()) && !Modifier.isAbstract(sig.getModifiers())) {
+ if (ResolvedTypeX.matches(sig, world.makeResolvedMember(abstractMethod))) {
+ return;
+ }
+ }
+ }
+ }
+
+ super.abstractMethodMustBeImplemented(type, abstractMethod);
+ }
+
+}
diff --git a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/AjBuildConfig.java b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/AjBuildConfig.java
new file mode 100644
index 000000000..8a43cfa33
--- /dev/null
+++ b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/AjBuildConfig.java
@@ -0,0 +1,205 @@
+/* *******************************************************************
+ * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC).
+ * All rights reserved.
+ * This program and the accompanying materials are made available
+ * under the terms of the Common Public License v1.0
+ * which accompanies this distribution and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * Xerox/PARC initial implementation
+ * ******************************************************************/
+
+
+package org.aspectj.ajdt.internal.core.builder;
+
+import java.io.File;
+import java.util.*;
+
+/**
+ * All configuration information needed to run the AspectJ compiler.
+ */
+public class AjBuildConfig {
+
+ public static final String AJLINT_INGORE = "ignore";
+ public static final String AJLINT_WARN = "warn";
+ public static final String AJLINT_ERROR = "error";
+ public static final String AJLINT_DEFAULT = "default";
+
+ private File outputDir;
+ private File outputJar;
+ private List/*File*/ sourceRoots = new ArrayList();
+ private List/*File*/ files = new ArrayList();
+ private List/*File*/ inJars = new ArrayList();
+ private List/*File*/ aspectpath = new ArrayList();
+ private List/*String*/ classpath = new ArrayList();
+ private Map javaOptions = new HashMap();
+ private Map ajOptions = new HashMap();
+ private File configFile;
+ private boolean generateModelMode = false;
+ private boolean emacsSymMode = false;
+ private boolean noWeave = false;
+ private boolean XserializableAspects = false;
+ private String lintMode = AJLINT_DEFAULT;
+ private File lintSpecFile = null;
+
+ /**
+ * returned files includes <ul>
+ * <li>files explicitly listed on command-line</li>
+ * <li>files listed by reference in argument list files</li>
+ * <li>files contained in sourceRootDir if that exists</li>
+ * </ul>
+ *
+ * @return all source files that should be compiled.
+ */
+ public List/*File*/ getFiles() {
+ return files;
+ }
+
+ public File getOutputDir() {
+ return outputDir;
+ }
+
+ public void setFiles(List files) {
+ this.files = files;
+ }
+
+ public void setOutputDir(File outputDir) {
+ this.outputDir = outputDir;
+ }
+
+ public Map getAjOptions() {
+ return ajOptions;
+ }
+
+ /**
+ * @return the Map expected by org.eclipse.jdt.core.internal.Compiler.
+ */
+ public Map getJavaOptions() {
+ return javaOptions;
+ }
+
+ public void setAjOptions(Map ajOptions) {
+ this.ajOptions = ajOptions;
+ }
+
+ public void setJavaOptions(Map javaOptions) {
+ this.javaOptions = javaOptions;
+ }
+
+ /**
+ * This includes all entries from -bootclasspath, -extdirs, -classpath,
+ */
+ public List getClasspath() {
+ return classpath;
+ }
+
+ public void setClasspath(List classpath) {
+ this.classpath = classpath;
+ }
+
+ public File getOutputJar() {
+ return outputJar;
+ }
+
+ public List/*File*/ getInJars() {
+ return inJars;
+ }
+
+ public void setOutputJar(File outputJar) {
+ this.outputJar = outputJar;
+ }
+
+ public void setInJars(List sourceJars) {
+ this.inJars = sourceJars;
+ }
+
+ public List getSourceRoots() {
+ return sourceRoots;
+ }
+
+ public void setSourceRoots(List sourceRootDir) {
+ this.sourceRoots = sourceRootDir;
+ }
+
+ public File getConfigFile() {
+ return configFile;
+ }
+
+ public void setConfigFile(File configFile) {
+ this.configFile = configFile;
+ }
+
+ public boolean isEmacsSymMode() {
+ return emacsSymMode;
+ }
+
+ public void setEmacsSymMode(boolean emacsSymMode) {
+ this.emacsSymMode = emacsSymMode;
+ }
+
+ public boolean isGenerateModelMode() {
+ return generateModelMode;
+ }
+
+ public void setGenerateModelMode(boolean structureModelMode) {
+ this.generateModelMode = structureModelMode;
+ }
+
+ /**
+ * This includes injars and aspectpath
+ */
+ public List getFullClasspath() {
+ if (inJars.isEmpty() && aspectpath.isEmpty()) return getClasspath();
+ List full = new ArrayList();
+ for (Iterator i = inJars.iterator(); i.hasNext(); ) {
+ full.add(((File)i.next()).getAbsolutePath());
+ }
+ for (Iterator i = aspectpath.iterator(); i.hasNext(); ) {
+ full.add(((File)i.next()).getAbsolutePath());
+ }
+ full.addAll(getClasspath());
+ return full;
+ }
+
+ public String getLintMode() {
+ return lintMode;
+ }
+
+ public File getLintSpecFile() {
+ return lintSpecFile;
+ }
+
+ public List getAspectpath() {
+ return aspectpath;
+ }
+
+ public boolean isNoWeave() {
+ return noWeave;
+ }
+
+ public void setLintMode(String lintMode) {
+ this.lintMode = lintMode;
+ }
+
+ public void setLintSpecFile(File lintSpecFile) {
+ this.lintSpecFile = lintSpecFile;
+ }
+
+ public void setAspectpath(List aspectpath) {
+ this.aspectpath = aspectpath;
+ }
+
+ public void setNoWeave(boolean noWeave) {
+ this.noWeave = noWeave;
+ }
+
+ public boolean isXserializableAspects() {
+ return XserializableAspects;
+ }
+
+ public void setXserializableAspects(boolean xserializableAspects) {
+ XserializableAspects = xserializableAspects;
+ }
+
+}
diff --git a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/AjBuildManager.java b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/AjBuildManager.java
new file mode 100644
index 000000000..34d0a95a2
--- /dev/null
+++ b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/AjBuildManager.java
@@ -0,0 +1,845 @@
+/* *******************************************************************
+ * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC).
+ * All rights reserved.
+ * This program and the accompanying materials are made available
+ * under the terms of the Common Public License v1.0
+ * which accompanies this distribution and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * Xerox/PARC initial implementation
+ * ******************************************************************/
+
+
+package org.aspectj.ajdt.internal.core.builder;
+
+import org.aspectj.ajdt.internal.compiler.AjCompiler;
+import org.aspectj.ajdt.internal.compiler.lookup.AjLookupEnvironment;
+import org.aspectj.ajdt.internal.compiler.lookup.EclipseWorld;
+import org.aspectj.ajdt.internal.compiler.parser.AjParser;
+import org.aspectj.ajdt.internal.compiler.problem.AjProblemReporter;
+import org.aspectj.asm.*;
+import org.aspectj.bridge.*;
+import org.aspectj.util.LangUtil;
+import org.aspectj.weaver.bcel.*;
+import org.aspectj.workbench.resources.*;
+import org.eclipse.core.internal.events.ResourceDelta;
+import org.eclipse.core.resources.*;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.jdt.core.compiler.IProblem;
+import org.eclipse.jdt.internal.compiler.*;
+import org.eclipse.jdt.internal.compiler.env.ICompilationUnit;
+import org.eclipse.jdt.internal.compiler.util.Util;
+import org.eclipse.jdt.internal.core.builder.*;
+import org.eclipse.jdt.internal.compiler.Compiler;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.*;
+import java.util.jar.*;
+
+public class AjBuildManager {
+
+ public static final IProject DEFAULT_PROJECT // XXX
+ = new SimpleProject(new Path(""), "DefaultProject");
+
+ private JavaBuilder javaBuilder;
+ private StructureModel structureModel;
+ private BuildNotifier buildNotifier = null;
+ public AjBuildConfig buildConfig;
+
+ private BcelWeaver bcelWeaver;
+ private BcelWorld bcelWorld;
+
+ /** temp handler for callbacks */
+ private IMessageHandler currentHandler; // XXX wrong lifecyle, used for callbacks
+
+ ClassFileCache classFileCache;
+
+ Set addedFiles;
+ Set deletedFiles;
+
+ public AjBuildManager(IMessageHandler holder) {
+ super();
+ LangUtil.throwIaxIfNull(holder, "holder");
+ }
+
+ /** @return true if we should generate a model as a side-effect */
+ public boolean doGenerateModel() {
+ return buildConfig.isGenerateModelMode();
+ }
+
+ /** @throws AbortException if check for runtime fails */
+ public boolean batchBuild(AjBuildConfig buildConfig, IMessageHandler handler)
+ throws IOException, AbortException {
+ final CountingMessageHandler counter = new CountingMessageHandler(handler);
+ handler = null; // fyi - use counter only
+ try {
+ setBuildConfig(buildConfig);
+ currentHandler = counter;
+ String check = checkRtJar(buildConfig);
+ // XXX MessageUtil.abortUnlessNull(counter, check);
+ if (check != null) {
+ // XXX change to ABORT?
+ IMessage message = new Message(check, Message.WARNING, null, null);
+ // give delegate a chance to implement different message (abort)?
+ counter.handleMessage(message);
+ throw new AbortException(message);
+ }
+
+ setupModel();
+ initBcelWorld(counter);
+ if (counter.hasErrors()) {
+ return false;
+ }
+ initJavaBuilder(counter);
+ if (counter.hasErrors()) {
+ return false;
+ }
+
+ //XXX disabling structure building until Mik can make it optional
+ if (buildConfig.isEmacsSymMode()) bcelWorld.setModel(StructureModelManager.INSTANCE.getStructureModel());
+ BatchBuilder builder = new BatchBuilder(javaBuilder, counter);
+ State newState = builder.run();
+ if (buildConfig.isEmacsSymMode()) {
+ new org.aspectj.ajdt.internal.core.builder.EmacsStructureModelManager().externalizeModel();
+ }
+// System.err.println("check error: " + counter + ", " +
+// counter.numMessages(IMessage.ERROR) + ", " + counter.numMessages(IMessage.FAIL, false));
+ if (counter.hasErrors()) {
+ return false;
+ }
+
+ boolean weaved = weaveAndGenerateClassFiles(newState);
+ //XXX more sturucture disabling until it's optional
+ if (false) StructureModelManager.INSTANCE.fireModelUpdated();
+ return weaved;
+ } catch (CoreException ce) {
+ counter.handleMessage(new Message("core exception", IMessage.ABORT, ce, null));
+ //messageAdapter.handleAbort("core exception", ce);
+ return false;
+ } finally {
+ currentHandler = null;
+ }
+ }
+
+ /** extruded method as testing backdoor */
+ IncrementalBuilder getIncrementalBuilder(IMessageHandler handler) {
+ return new IncrementalBuilder(javaBuilder, handler);
+ }
+
+ private void setupModel() {
+ String rootLabel = "<root>";
+ if (buildConfig.getConfigFile() != null) {
+ rootLabel = buildConfig.getConfigFile().getName();
+ StructureModelManager.INSTANCE.getStructureModel().setConfigFile(
+ buildConfig.getConfigFile().getAbsolutePath()
+ );
+ }
+ StructureModelManager.INSTANCE.getStructureModel().setRoot(
+ new ProgramElementNode(
+ rootLabel,
+ ProgramElementNode.Kind.FILE_JAVA,
+ new ArrayList()));
+
+ HashMap modelFileMap = new HashMap();
+ StructureModelManager.INSTANCE.getStructureModel().setFileMap(new HashMap());
+ setStructureModel(StructureModelManager.INSTANCE.getStructureModel());
+
+ }
+
+ public boolean incrementalBuild(AjBuildConfig buildConfig, IMessageHandler messageHandler) throws CoreException, IOException {
+ try {
+ currentHandler = messageHandler;
+ IncrementalBuilder builder = getIncrementalBuilder(messageHandler);
+ // SimpleLookupTable deltas =
+ //XXX for Mik, replace this with a call to builder.build(SimpleLookupTable deltas)
+
+ IContainer[] sourceFolders = new IContainer[buildConfig.getSourceRoots().size()];
+ int count = 0;
+ for (Iterator i = buildConfig.getSourceRoots().iterator(); i.hasNext(); count++) {
+ sourceFolders[count] = new FilesystemFolder(((File)i.next()).getAbsolutePath());
+ }
+ builder.setSourceFolders(sourceFolders);
+ getJavaBuilder().binaryResources = new SimpleLookupTable();
+ SimpleLookupTable deltas = getDeltas(buildConfig);
+
+ boolean succeeded = builder.build(deltas);
+
+ if (succeeded) {
+ return weaveAndGenerateClassFiles(builder.getNewState());
+ } else {
+ return batchBuild(buildConfig, messageHandler);
+ }
+ } finally {
+ currentHandler = null;
+ }
+
+ }
+
+ SimpleLookupTable getDeltas(AjBuildConfig newBuildConfig) {
+ updateBuildConfig(newBuildConfig);
+ // !!! support multiple source roots
+ SimpleLookupTable deltas = new SimpleLookupTable();
+ for (Iterator i = newBuildConfig.getSourceRoots().iterator(); i.hasNext(); ) {
+ makeDeltas(deltas, getModifiedFiles(), deletedFiles, ((File)i.next()).getAbsolutePath());
+ }
+ return deltas;
+ }
+
+ void makeDeltas(SimpleLookupTable deltas, Collection modifiedAndAdded, Collection deletedFiles, String sourcePath) {
+
+ IProject project = javaBuilder.currentProject; //???
+
+ List deltaChildren = new ArrayList();
+ //??? do we need to distinguish added from modified
+// for (Iterator it = addedFiles.iterator(); it.hasNext(); ) {
+// File addedFile = (File)it.next();
+// CommandLineResourceDelta addedDelta = new CommandLineResourceDelta(
+// new Path(addedFile.getAbsolutePath()), null);
+// addedDelta.setKind(IResourceDelta.ADDED);
+// deltaChildren.add(addedDelta);
+// }
+
+ for (Iterator it = deletedFiles.iterator(); it.hasNext(); ) {
+ File addedFile = (File)it.next();
+ CommandLineResourceDelta addedDelta = new CommandLineResourceDelta(
+ new FilesystemFile(addedFile.getAbsolutePath()));
+ addedDelta.setKind(IResourceDelta.REMOVED);
+ deltaChildren.add(addedDelta);
+ }
+
+ for (Iterator it = modifiedAndAdded.iterator(); it.hasNext(); ) {
+ File addedFile = (File)it.next();
+ CommandLineResourceDelta addedDelta = new CommandLineResourceDelta(
+ new FilesystemFile(addedFile.getAbsolutePath()));
+ addedDelta.setKind(IResourceDelta.CHANGED);
+ deltaChildren.add(addedDelta);
+ }
+
+ CommandLineResourceDelta delta = new CommandLineResourceDelta(
+ new FilesystemFile(sourcePath));
+ delta.setKind(IResourceDelta.CHANGED);
+ delta.setChildren((ResourceDelta[])deltaChildren.toArray(new ResourceDelta[deltaChildren.size()]));
+ deltas.put(project,delta);
+ }
+
+ void updateBuildConfig(AjBuildConfig newBuildConfig) {
+ Set oldFiles = new HashSet(buildConfig.getFiles());
+ Set newFiles = new HashSet(newBuildConfig.getFiles());
+
+ addedFiles = new HashSet(newFiles);
+ addedFiles.removeAll(oldFiles);
+ deletedFiles = new HashSet(oldFiles);
+ deletedFiles.removeAll(newFiles);
+ setBuildConfig(newBuildConfig);
+ }
+
+ private void initBcelWorld(IMessageHandler handler) throws IOException {
+ bcelWorld = new BcelWorld(buildConfig.getClasspath(), handler);
+ bcelWeaver = new BcelWeaver(bcelWorld);
+
+ for (Iterator i = buildConfig.getAspectpath().iterator(); i.hasNext();) {
+ File f = (File) i.next();
+ bcelWeaver.addLibraryJarFile(f);
+ }
+
+ String lintMode = buildConfig.getLintMode();
+
+ if (buildConfig.getLintMode().equals(AjBuildConfig.AJLINT_DEFAULT)) {
+ bcelWorld.getLint().loadDefaultProperties();
+ } else {
+ bcelWorld.getLint().setAll(buildConfig.getLintMode());
+ }
+
+ if (buildConfig.getLintSpecFile() != null) {
+ bcelWorld.getLint().setFromProperties(buildConfig.getLintSpecFile());
+ }
+ }
+
+ //??? do this well
+ private void initJavaBuilder(IMessageHandler handler) {
+ javaBuilder = new JavaBuilder();
+ javaBuilder.currentProject = DEFAULT_PROJECT;
+ if (buildConfig.getOutputDir() == null) {
+ //XXX must handle this case better to get javac output compatibility
+ javaBuilder.outputFolder = new FilesystemFolder(new Path("."));
+ } else {
+ javaBuilder.outputFolder = new FilesystemFolder(new Path(buildConfig.getOutputDir().getPath())); //outputDir.getPath()));
+ }
+ classFileCache = new ClassFileCache(javaBuilder.outputFolder, handler);
+ javaBuilder.outputFolder = classFileCache;
+
+ javaBuilder.sourceFolders = new IContainer[0];
+
+ javaBuilder.classpath = makeClasspathLocations();
+
+ //XXX override build notifier to get progress info
+ if (buildNotifier == null) buildNotifier = new BuildNotifier(null, javaBuilder.currentProject);
+ javaBuilder.notifier = buildNotifier;
+ }
+
+ public static String[] getFilenames(List files) {
+ int len = files.size();
+ String[] ret = new String[len];
+ for (int i=0; i < len; i++) {
+ File file = (File)files.get(i);
+ ret[i] = file.getPath();
+ }
+ return ret;
+ }
+
+ public static String[] getInitialTypeNames(List files) {
+ int len = files.size();
+ String[] ret = new String[len];
+ for (int i=0; i < len; i++) {
+ File file = (File)files.get(i);
+ String name = file.getName();
+ int dot = name.indexOf('.'); //XXX what if there's no '.'
+ ret[i] = name.substring(0, dot);
+ }
+ return ret;
+ }
+
+ void addAspectClassFilesToWeaver() throws IOException {
+ //System.out.println("added or changed: " + classFileCache.getAddedOrChanged());
+ for (Iterator i = buildConfig.getInJars().iterator(); i.hasNext(); ) {
+ File inJar = (File)i.next();
+ bcelWeaver.addJarFile(inJar, buildConfig.getOutputDir());
+ }
+
+ for (Iterator i = classFileCache.getAddedOrChanged().iterator(); i.hasNext(); ) {
+ UnwovenClassFile classFile = (UnwovenClassFile) i.next();
+ bcelWeaver.addClassFile(classFile);
+ }
+ for (Iterator i = classFileCache.getDeleted().iterator(); i.hasNext(); ) {
+ UnwovenClassFile classFile = (UnwovenClassFile) i.next();
+ bcelWeaver.deleteClassFile(classFile.getClassName());
+ classFile.deleteRealFile();
+ }
+ }
+
+ public boolean weaveAndGenerateClassFiles(State newState) throws IOException, CoreException {
+ currentHandler.handleMessage(MessageUtil.info("weaving"));
+ javaBuilder.lastState = newState;
+ addAspectClassFilesToWeaver();
+ if (buildConfig.isNoWeave()) {
+ if (buildConfig.getOutputJar() != null) {
+ bcelWeaver.dumpUnwoven(buildConfig.getOutputJar());
+ } else {
+ bcelWeaver.dumpUnwoven();
+ }
+ } else {
+ if (buildConfig.getOutputJar() != null) {
+ bcelWeaver.weave(buildConfig.getOutputJar());
+ } else {
+ bcelWeaver.weave();
+ }
+ }
+ return true;
+ //return messageAdapter.getErrorCount() == 0; //!javaBuilder.notifier.anyErrors();
+ }
+
+ /** TEST-ONLY access to builder */
+ JavaBuilder getJavaBuilder() {
+ return javaBuilder;
+ }
+
+ private void setBuildConfig(AjBuildConfig buildConfig) {
+ this.buildConfig = buildConfig;
+
+ // clear previous error info and incremental info when build config is set
+ if (javaBuilder != null) {
+ javaBuilder.notifier = new BuildNotifier(null, javaBuilder.currentProject);
+ }
+ if (classFileCache != null) {
+ classFileCache.resetIncrementalInfo();
+ }
+ }
+
+ private Collection getModifiedFiles() {
+ return getModifiedFiles(javaBuilder.lastState.lastStructuralBuildTime);
+ }
+
+ Collection getModifiedFiles(long lastBuildTime) {
+ List ret = new ArrayList();
+ //not our job to account for new and deleted files
+ for (Iterator i = buildConfig.getFiles().iterator(); i.hasNext(); ) {
+ File file = (File)i.next();
+
+ long modTime = file.lastModified();
+ //System.out.println("check: " + file + " mod " + modTime + " build " + lastBuildTime);
+ if (modTime > lastBuildTime) {
+ ret.add(file);
+ }
+ }
+ return ret;
+ }
+
+ ClasspathLocation makeClasspathLocation(String entry) {
+ if (entry.endsWith(".jar") || entry.endsWith(".zip")) {
+ return ClasspathLocation.forLibrary(entry);
+ } else {
+ return ClasspathLocation.forBinaryFolder(entry);
+ }
+ }
+
+ ClasspathLocation makeUnwovenClassfileLocation(IContainer container) {
+ return new ClasspathContainer(container);
+ }
+
+ /**
+ * Adds in this order<UL>
+ * skip this for now, incremental may need some version<LI>magic source path
+ * <LI>output path
+ * <LI>classpath
+ * </UL>
+ */
+ ClasspathLocation[] makeClasspathLocations() {
+ List locations = new ArrayList();
+
+ locations.add(makeUnwovenClassfileLocation(classFileCache));
+
+ //System.out.println("full classpath: " + buildConfig.getFullClasspath());
+
+ for (Iterator it = buildConfig.getFullClasspath().iterator(); it.hasNext(); ) {
+ locations.add(makeClasspathLocation((String)it.next()));
+ }
+ return (ClasspathLocation[])locations.toArray(new ClasspathLocation[locations.size()]);
+ }
+
+
+ String makeClasspathString() {
+ if (buildConfig == null || buildConfig.getClasspath() == null) return "";
+ StringBuffer buf = new StringBuffer();
+ boolean first = true;
+ for (Iterator it = buildConfig.getClasspath().iterator(); it.hasNext(); ) {
+ if (first) { first = false; }
+ else { buf.append(File.pathSeparator); }
+ buf.append(it.next().toString());
+ }
+ return buf.toString();
+ }
+
+
+ /**
+ * This will return null if aspectjrt.jar is present and has the correct version.
+ * Otherwise it will return a string message indicating the problem.
+ */
+ public String checkRtJar(AjBuildConfig buildConfig) {
+ // omitting dev info
+ if (Version.text.equals(Version.DEVELOPMENT)) {
+ // in the development version we can't do this test usefully
+// MessageUtil.info(holder, "running development version of aspectj compiler");
+ return null;
+ }
+
+ if (buildConfig == null || buildConfig.getClasspath() == null) return "no classpath specified";
+ for (Iterator it = buildConfig.getClasspath().iterator(); it.hasNext(); ) {
+ File p = new File( (String)it.next() );
+ if (p.isFile() && p.getName().equals("aspectjrt.jar")) {
+
+ try {
+ String version = null;
+ Attributes attr = new JarFile(p).getManifest().getAttributes("org/aspectj/lang/");
+ if (null != attr) {
+ version = attr.getValue(Attributes.Name.IMPLEMENTATION_VERSION);
+ if (null != version) {
+ version = version.trim();
+ }
+ }
+ // assume that users of development aspectjrt.jar know what they're doing
+ if (Version.DEVELOPMENT.equals(version)) {
+// MessageUtil.info(holder,
+// "running with development version of aspectjrt.jar in " +
+// p.getAbsolutePath());
+ return null;
+ } else if (!Version.text.equals(version)) {
+ return "bad version number found in " + p.getAbsolutePath() +
+ " expected " + Version.text + " found " + version;
+ }
+ } catch (IOException ioe) {
+ return "bad jar file found in " + p.getAbsolutePath() + " error: " + ioe;
+ }
+ return null;
+ } else {
+ // might want to catch other classpath errors
+ }
+ }
+
+ return "couldn't find aspectjrt.jar on classpath, checked: " + makeClasspathString();
+ }
+
+
+ /**
+ * Just like AbstractImageBuilder.newCompiler, except doesn't use JavaCore
+ */
+ Compiler makeCompiler( // XXX restore private
+ final AbstractImageBuilder builder,
+ NameEnvironment nameEnvironment,
+ IMessageHandler handler) {
+ // called once when the builder is initialized... can override if needed
+ AjCompiler compiler = new AjCompiler(
+ nameEnvironment,
+ DefaultErrorHandlingPolicies.proceedWithAllProblems(),
+ buildConfig.getJavaOptions(),
+ builder,
+ ProblemFactory.getProblemFactory(Locale.getDefault()));
+
+
+ AjProblemReporter pr = new AjProblemReporter(DefaultErrorHandlingPolicies.proceedWithAllProblems(),
+ compiler.options, ProblemFactory.getProblemFactory(Locale.getDefault()));
+
+ compiler.problemReporter = pr;
+
+ AjLookupEnvironment le =
+ new AjLookupEnvironment(compiler, compiler.options,
+ pr, nameEnvironment);
+ EclipseWorld ew = new EclipseWorld(le, handler);
+ ew.setLint(bcelWorld.getLint());
+ le.world = ew;
+ pr.world = ew;
+ le.world.buildManager = this;
+
+ compiler.lookupEnvironment = le;
+
+ compiler.parser =
+ new AjParser(
+ pr,
+ compiler.options.parseLiteralExpressionsAsConstants,
+ compiler.options.assertMode);
+
+
+
+ //EclipseWorld world = EclipseWorld.forLookupEnvironment(compiler.lookupEnvironment);
+ return compiler;
+ }
+
+ public String toString() {
+ StringBuffer buf = new StringBuffer();
+ buf.append("AjBuildManager(");
+ buf.append(")");
+ return buf.toString();
+ }
+
+
+ public void setStructureModel(StructureModel structureModel) {
+ this.structureModel = structureModel;
+ }
+
+ /**
+ * Returns null if there is no structure model
+ */
+ public StructureModel getStructureModel() {
+ return structureModel;
+ }
+
+ public void setBuildNotifier(BuildNotifier notifier) {
+ buildNotifier = notifier;
+ }
+
+ /** callback for builders used only during build */
+ private boolean handleProblem(ICompilationUnit unit, IProblem problem) { // XXX
+ IMessageHandler handler = currentHandler;
+ if (null == handler) {
+ throw new IllegalStateException("no current handler when handling "
+ + problem + " in " + unit);
+ }
+ IMessage message = EclipseAdapterUtils.makeMessage(unit, problem);
+ return handler.handleMessage(message);
+ }
+
+ /** initialization for testing purposes */
+ boolean testInit(IMessageHandler handler) {
+ try {
+ initBcelWorld(handler);
+ initJavaBuilder(handler);
+ } catch (Throwable e) {
+ return false;
+ }
+ return true;
+ }
+ /** invasive test has to set handler */
+ void testSetHandler(IMessageHandler handler) {
+ currentHandler = handler;
+ }
+
+ // ----------------------------------------------------
+
+ /** build batch command; alive during batchBuild(...) only */
+ private class BatchBuilder extends BatchImageBuilder {
+ boolean initialized;
+ boolean running;
+
+ public BatchBuilder(JavaBuilder builder, IMessageHandler handler) {
+ super(builder);
+ this.compiler = makeCompiler(this, nameEnvironment, handler);
+ }
+
+ /**
+ * XXXwe'll want to preload aspects from projects or library .jars
+ * XXXthat we depend on
+ *
+ * compile all files and store in generatedClassFiles
+ * then collect aspects
+ * then weave into generatedClassFiles and dump to disk
+ *
+ * a possible optimization is to generate all aspects first, it's unclear
+ * that this is worth the effort or loss of clarity
+ */
+ public State run() throws IOException, CoreException {
+ compile(getFilenames(buildConfig.getFiles()),
+ getInitialTypeNames(buildConfig.getFiles()));
+ return newState;
+ }
+
+ /**
+ * Only used to get source files
+ *
+ * XXX verify this rigourously
+ */
+ protected IResource resourceForLocation(String sourceLocation) {
+ return new FilesystemFile(new Path(sourceLocation));
+ }
+
+ protected void createErrorFor(IResource resource, String message) {
+ //XXX don't think there's anything to do here
+ }
+
+ protected void updateProblemsFor(
+ String sourceLocation,
+ CompilationResult result)
+ throws CoreException {
+ IProblem[] problems = result.getProblems();
+ if (problems == null || problems.length == 0) return;
+
+ notifier.updateProblemCounts(problems);
+ for (int i=0, len=problems.length; i < len; i++) {
+ handleProblem(result.getCompilationUnit(), problems[i]);
+ }
+ }
+
+ /**
+ * We can't create a compiler until after our super's constructor has run
+ * We will fill in the right value then.
+ */
+ protected Compiler newCompiler() { // XXX unimplemented??
+ return null;
+ }
+
+ protected SourceFile makeSourceFile(String filename, String initialTypeName) {
+ SourceFile sourceFile = super.makeSourceFile(filename, initialTypeName);
+ sourceFile.packageName = null; // tells eclipse that we don't know this package
+ return sourceFile;
+ }
+ } // class BatchBuilder
+
+ class IncrementalBuilder extends IncrementalImageBuilder {
+
+ public IncrementalBuilder(JavaBuilder builder, IMessageHandler handler) {
+ super(builder);
+ this.compiler = makeCompiler(this, nameEnvironment, handler);
+ }
+
+
+ List getLocations() {
+ return locations;
+ }
+
+ public State getNewState() {
+ return newState;
+ }
+
+ public boolean build(SimpleLookupTable deltas) {
+ return super.build(deltas);
+ }
+
+ /**
+ * @param changedFiles includes both new files and changed files
+ */
+ public boolean build(Collection changedFiles, Collection deletedFiles) {
+
+ // initialize builder
+ // walk this project's deltas, find changed source files
+ // walk prereq projects' deltas, find changed class files & add affected source files
+ // use the build state # to skip the deltas for certain prereq projects
+ // ignore changed zip/jar files since they caused a full build
+ // compile the source files & acceptResult()
+ // compare the produced class files against the existing ones on disk
+ // recompile all dependent source files of any type with structural changes or new/removed secondary type
+ // keep a loop counter to abort & perform a full build
+
+ if (JavaBuilder.DEBUG)
+ System.out.println("INCREMENTAL build"); //$NON-NLS-1$
+
+ try {
+ resetCollections();
+
+ notifier.subTask(Util.bind("build.analyzingDeltas")); //$NON-NLS-1$
+ if (!addFileLocations(changedFiles, deletedFiles)) return false;
+
+ //XXX deal with deleted files here too
+
+
+ // IResourceDelta sourceDelta = (IResourceDelta) deltas.get(javaBuilder.currentProject);
+ // if (sourceDelta != null)
+ // if (!findSourceFiles(sourceDelta)) return false;
+ // notifier.updateProgressDelta(0.10f);
+
+ // Object[] keyTable = deltas.keyTable;
+ // Object[] valueTable = deltas.valueTable;
+ // for (int i = 0, l = keyTable.length; i < l; i++) {
+ // IResourceDelta delta = (IResourceDelta) valueTable[i];
+ // if (delta != null) {
+ // IResource[] binaryResources = (IResource[]) javaBuilder.binaryResources.get(keyTable[i]);
+ // if (binaryResources != null)
+ // if (!findAffectedSourceFiles(delta, binaryResources)) return false;
+ // }
+ // }
+ // notifier.updateProgressDelta(0.10f);
+
+ notifier.subTask(Util.bind("build.analyzingSources")); //$NON-NLS-1$
+ addAffectedSourceFiles();
+ notifier.updateProgressDelta(0.05f);
+
+ int compileLoop = 0;
+ float increment = 0.40f;
+ while (locations.size() > 0) { // added to in acceptResult
+ if (++compileLoop > MaxCompileLoop) {
+ if (JavaBuilder.DEBUG)
+ System.out.println("ABORTING incremental build... exceeded loop count"); //$NON-NLS-1$
+ return false;
+ }
+ notifier.checkCancel();
+
+ String[] allSourceFiles = new String[locations.size()];
+ locations.toArray(allSourceFiles);
+ String[] initialTypeStrings = new String[typeNames.size()];
+ typeNames.toArray(initialTypeStrings);
+ resetCollections();
+
+ workQueue.addAll(allSourceFiles);
+ notifier.setProgressPerCompilationUnit(increment / allSourceFiles.length);
+ increment = increment / 2;
+ compile(allSourceFiles, initialTypeStrings);
+ //removeSecondaryTypes();
+ addAffectedSourceFiles();
+ }
+ } catch (AbortIncrementalBuildException e) {
+ // abort the incremental build and let the batch builder handle the problem
+ if (JavaBuilder.DEBUG)
+ System.out.println("ABORTING incremental build... cannot find " + e.qualifiedTypeName + //$NON-NLS-1$
+ ". Could have been renamed inside its existing source file."); //$NON-NLS-1$
+ return false;
+ // } catch (CoreException e) {
+ // throw internalException(e);
+ } finally {
+ cleanUp();
+ }
+ return true;
+ }
+
+ public void setSourceFolders(IContainer[] sourceFolders) {
+ super.sourceFolders = sourceFolders;
+ }
+
+ public IContainer[] getSourceFolders() {
+ return sourceFolders;
+ }
+
+ private boolean addFileLocations(Collection changedFiles, Collection deletedFiles) {
+ addDeletedFiles(deletedFiles);
+
+ for (Iterator i = changedFiles.iterator(); i.hasNext(); ) {
+ File file = (File)i.next();
+ locations.add(getSourceLocation(file));
+ typeNames.add(file.getName().substring(0, file.getName().length()-5));
+ }
+ return changedFiles.size() > 0 || deletedFiles.size() > 0;
+ }
+
+ private String getSourceLocation(File file) {
+ return file.getPath().replace('\\', '/');
+ }
+
+
+ /**
+ * @see IncrementalImageBuilder.findSourceFiles
+ */
+ private void addDeletedFiles(Collection deletedFiles) {
+ }
+ // for (Iterator i = deletedFiles.iterator(); i.hasNext(); ) {
+ // File file = (File)i.next();
+ // String sourceLocation = getSourceLocation(file);
+ // char[][] definedTypeNames = newState.getDefinedTypeNamesFor(sourceLocation);
+ //
+ // if (definedTypeNames == null) { // defined a single type matching typePath
+ // removeClassFile(typePath);
+ // } else {
+ // if (JavaBuilder.DEBUG)
+ // System.out.println("Add dependents of removed source file " + typePath.toString()); //$NON-NLS-1$
+ // addDependentsOf(typePath, true); // add dependents of the source file since it may be involved in a name collision
+ // if (definedTypeNames.length > 0) { // skip it if it failed to successfully define a type
+ // IPath packagePath = typePath.removeLastSegments(1);
+ // for (int i = 0, length = definedTypeNames.length; i < length; i++)
+ // removeClassFile(packagePath.append(new String(definedTypeNames[i])));
+ // }
+ // }
+ // newState.remove(sourceLocation);
+ // }
+
+
+ // public void acceptResult(CompilationResult result) {
+ // System.out.println("result: " + result);
+ // buildManager.noteRecompiled(new File(new String(result.fileName)));
+ // //newState.dump();
+ // super.acceptResult(result);
+ // //newState.dump();
+ // }
+
+ protected IResource resourceForLocation(String sourceLocation) {
+ return new FilesystemFile(new Path(sourceLocation));
+ }
+
+ protected void createErrorFor(IResource resource, String message) {
+ //XXX don't think there's anything to do here
+ }
+
+ protected void updateProblemsFor(
+ String sourceLocation,
+ CompilationResult result)
+ throws CoreException {
+ IProblem[] problems = result.getProblems();
+ if (problems == null || problems.length == 0) return;
+
+ notifier.updateProblemCounts(problems);
+ for (int i=0, len=problems.length; i < len; i++) {
+ handleProblem(result.getCompilationUnit(), problems[i]);
+ }
+ }
+
+
+ protected String extractTypeNameFrom(String sourceLocation) {
+ File file = new File(sourceLocation);
+ return file.getName().substring(0, file.getName().length()-5);
+ }
+
+ /**
+ * We can't create a compiler until after our super's constructor has run
+ * We will fill in the right value then.
+ */
+ protected Compiler newCompiler() {
+ return null;
+ }
+
+ protected SourceFile makeSourceFile(String filename, String initialTypeName) {
+ SourceFile sourceFile = super.makeSourceFile(filename, initialTypeName);
+ sourceFile.packageName = null; // tells eclipse that we don't know this package
+ return sourceFile;
+ }
+
+ } // class IncrementalBuilder
+
+} // class AjBuildManager
+
diff --git a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/AjCompilerOptions.java b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/AjCompilerOptions.java
new file mode 100644
index 000000000..e3545ea39
--- /dev/null
+++ b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/AjCompilerOptions.java
@@ -0,0 +1,28 @@
+/* *******************************************************************
+ * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC).
+ * All rights reserved.
+ * This program and the accompanying materials are made available
+ * under the terms of the Common Public License v1.0
+ * which accompanies this distribution and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * Xerox/PARC initial implementation
+ * ******************************************************************/
+
+
+package org.aspectj.ajdt.internal.core.builder;
+
+import java.util.Map;
+
+/**
+ * ??? should this go away?
+ */
+public class AjCompilerOptions {
+
+ public static final String OPTION_Xlint = "org.aspectj.ajdt.core.compiler.Xlint";
+ public static final String OPTION_InJARs = "org.aspectj.ajdt.core.compiler.injars";
+ public static final String OPTION_OutJAR = "org.aspectj.ajdt.core.compiler.outjar";
+
+}
+
diff --git a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/AjNameEnvironment.java b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/AjNameEnvironment.java
new file mode 100644
index 000000000..3e65a5da8
--- /dev/null
+++ b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/AjNameEnvironment.java
@@ -0,0 +1,40 @@
+/* *******************************************************************
+ * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC).
+ * All rights reserved.
+ * This program and the accompanying materials are made available
+ * under the terms of the Common Public License v1.0
+ * which accompanies this distribution and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * Xerox/PARC initial implementation
+ * ******************************************************************/
+
+
+package org.aspectj.ajdt.internal.core.builder;
+
+import java.util.*;
+
+import org.aspectj.ajdt.internal.compiler.ast.*;
+import org.eclipse.jdt.core.*;
+import org.eclipse.jdt.internal.core.builder.*;
+
+public class AjNameEnvironment extends NameEnvironment {
+ private Set aspectDeclarations = new HashSet();
+
+ public AjNameEnvironment(ClasspathLocation[] classpathLocations) {
+ super(classpathLocations);
+ }
+
+ public AjNameEnvironment(IJavaProject javaProject) {
+ super(javaProject);
+ }
+
+ //??? do I want this or a more general getAspects???
+ public Collection getAspectDeclarations() { return aspectDeclarations; }
+
+ public void addAspectDeclaration(AspectDeclaration dec) {
+ aspectDeclarations.add(dec);
+ }
+
+}
diff --git a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/AsmBuilder.java b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/AsmBuilder.java
new file mode 100644
index 000000000..6abd8b518
--- /dev/null
+++ b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/AsmBuilder.java
@@ -0,0 +1,317 @@
+/* *******************************************************************
+ * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC).
+ * All rights reserved.
+ * This program and the accompanying materials are made available
+ * under the terms of the Common Public License v1.0
+ * which accompanies this distribution and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * Xerox/PARC initial implementation
+ * ******************************************************************/
+
+
+package org.aspectj.ajdt.internal.core.builder;
+
+import java.io.File;
+import java.text.CollationElementIterator;
+import java.util.*;
+import java.util.List;
+
+import org.aspectj.ajdt.internal.compiler.ast.*;
+import org.aspectj.ajdt.internal.compiler.ast.AdviceDeclaration;
+import org.aspectj.ajdt.internal.compiler.lookup.*;
+import org.aspectj.ajdt.internal.compiler.lookup.EclipseShadow;
+import org.aspectj.asm.*;
+import org.aspectj.asm.StructureModel;
+import org.aspectj.bridge.*;
+import org.aspectj.bridge.ISourceLocation;
+import org.aspectj.weaver.Member;
+import org.eclipse.jdt.core.dom.ASTNode;
+import org.eclipse.jdt.internal.compiler.*;
+import org.eclipse.jdt.internal.compiler.AbstractSyntaxTreeVisitorAdapter;
+import org.eclipse.jdt.internal.compiler.ast.*;
+import org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration;
+import org.eclipse.jdt.internal.compiler.impl.ReferenceContext;
+import org.eclipse.jdt.internal.compiler.lookup.*;
+import org.eclipse.jdt.internal.compiler.lookup.CompilationUnitScope;
+import org.eclipse.jdt.internal.compiler.problem.ProblemHandler;
+
+public class AsmBuilder extends AbstractSyntaxTreeVisitorAdapter {
+
+ private Stack stack = new Stack();
+ private CompilationResult currCompilationResult = null;
+
+ public static void build(
+ CompilationUnitDeclaration unit,
+ StructureModel structureModel) {
+ new AsmBuilder().internalBuild(unit, structureModel);
+ }
+
+ private void internalBuild(CompilationUnitDeclaration unit, StructureModel structureModel) {
+ currCompilationResult = unit.compilationResult();
+ File file = new File(new String(unit.getFileName()));
+ ISourceLocation sourceLocation = new SourceLocation(file, 1);
+
+ ProgramElementNode cuNode = new ProgramElementNode(
+ new String(file.getName()),
+ ProgramElementNode.Kind.FILE_JAVA,
+ sourceLocation,
+ 0,
+ "",
+ new ArrayList());
+
+ ImportReference currentPackage = unit.currentPackage;
+ if (currentPackage != null) {
+ StringBuffer nameBuffer = new StringBuffer();
+ for (int i = 0; i < currentPackage.getImportName().length; i++) {
+ nameBuffer.append(new String(currentPackage.getImportName()[i]));
+ if (i < currentPackage.getImportName().length-1) nameBuffer.append('.');
+ }
+ String pkgName = nameBuffer.toString();
+
+ boolean found = false;
+ ProgramElementNode pkgNode = null;
+ for (Iterator it = StructureModelManager.INSTANCE.getStructureModel().getRoot().getChildren().iterator(); it.hasNext(); ) {
+ ProgramElementNode currNode = (ProgramElementNode)it.next();
+ if (currNode.getName().equals(pkgName)) pkgNode = currNode;
+ }
+ if (pkgNode == null) {
+ pkgNode = new ProgramElementNode(
+ pkgName,
+ ProgramElementNode.Kind.PACKAGE,
+ new ArrayList());
+ StructureModelManager.INSTANCE.getStructureModel().getRoot().addChild(pkgNode);
+ }
+ pkgNode.addChild(cuNode);
+ } else {
+ StructureModelManager.INSTANCE.getStructureModel().getRoot().addChild(cuNode);
+ }
+
+ stack.push(cuNode);
+ unit.traverse(this, unit.scope);
+
+ StructureModelManager.INSTANCE.getStructureModel().getFileMap().put(
+ file.getAbsolutePath().replace('\\', '/'),
+ cuNode
+ );
+// if (currImports != null) peNode.addChild(0, currImports);
+// currImports = null;
+ }
+
+ public boolean visit(TypeDeclaration typeDeclaration, CompilationUnitScope scope) {
+ String name = new String(typeDeclaration.name);
+ ProgramElementNode.Kind kind = ProgramElementNode.Kind.CLASS;
+ if (typeDeclaration instanceof AspectDeclaration) kind = ProgramElementNode.Kind.ASPECT;
+ else if (typeDeclaration.isInterface()) kind = ProgramElementNode.Kind.INTERFACE;
+
+ ProgramElementNode peNode = new ProgramElementNode(
+ name,
+ kind,
+ makeLocation(typeDeclaration),
+ typeDeclaration.modifiers,
+ "",
+ new ArrayList());
+
+ ((StructureNode)stack.peek()).addChild(peNode);
+ stack.push(peNode);
+ return true;
+ }
+ public void endVisit(TypeDeclaration typeDeclaration, CompilationUnitScope scope) {
+ stack.pop();
+ }
+
+ // ??? share impl with visit(TypeDeclaration, ..) ?
+ public boolean visit(MemberTypeDeclaration memberTypeDeclaration, ClassScope scope) {
+ String name = new String(memberTypeDeclaration.name);
+ ProgramElementNode.Kind kind = ProgramElementNode.Kind.CLASS;
+ if (memberTypeDeclaration instanceof AspectDeclaration) kind = ProgramElementNode.Kind.ASPECT;
+ else if (memberTypeDeclaration.isInterface()) kind = ProgramElementNode.Kind.INTERFACE;
+
+ ProgramElementNode peNode = new ProgramElementNode(
+ name,
+ kind,
+ makeLocation(memberTypeDeclaration),
+ memberTypeDeclaration.modifiers,
+ "",
+ new ArrayList());
+
+ ((StructureNode)stack.peek()).addChild(peNode);
+ stack.push(peNode);
+ return true;
+ }
+ public void endVisit(MemberTypeDeclaration memberTypeDeclaration, ClassScope scope) {
+ stack.pop();
+ }
+
+ // !!! improve name and type generation
+ public boolean visit(MethodDeclaration methodDeclaration, ClassScope scope) {
+ ProgramElementNode.Kind kind = ProgramElementNode.Kind.METHOD;
+ String label = new String(methodDeclaration.selector);
+
+ if (methodDeclaration instanceof AdviceDeclaration) {
+ kind = ProgramElementNode.Kind.ADVICE;
+ label = translateAdviceName(label);
+ } else if (methodDeclaration instanceof PointcutDeclaration) {
+ kind = ProgramElementNode.Kind.POINTCUT;
+ } else if (methodDeclaration instanceof DeclareDeclaration) {
+ DeclareDeclaration declare = (DeclareDeclaration)methodDeclaration;
+ label = translateDeclareName(declare.toString());
+ if (label.indexOf("warning") != -1) kind = ProgramElementNode.Kind.DECLARE_WARNING;
+ if (label.indexOf("error") != -1) kind = ProgramElementNode.Kind.DECLARE_ERROR;
+ } else if (methodDeclaration instanceof InterTypeDeclaration) {
+ kind = ProgramElementNode.Kind.INTRODUCTION;
+ label = translateInterTypeDecName(new String(((InterTypeDeclaration)methodDeclaration).selector));
+ }
+
+ ProgramElementNode peNode = new ProgramElementNode(
+ label,
+ kind,
+ makeLocation(methodDeclaration),
+ methodDeclaration.modifiers,
+ "",
+ new ArrayList());
+
+ Member member = EclipseWorld.makeResolvedMember(methodDeclaration.binding);
+ peNode.setBytecodeName(member.getName());
+ peNode.setBytecodeSignature(member.getSignature());
+ ((StructureNode)stack.peek()).addChild(peNode);
+ stack.push(peNode);
+
+ return true;
+ }
+
+
+ public void endVisit(MethodDeclaration methodDeclaration, ClassScope scope) {
+ stack.pop();
+ }
+
+ public boolean visit(FieldDeclaration fieldDeclaration, MethodScope scope) {
+ ProgramElementNode peNode = new ProgramElementNode(
+ new String(fieldDeclaration.name),
+ ProgramElementNode.Kind.FIELD,
+ makeLocation(fieldDeclaration),
+ fieldDeclaration.modifiers,
+ "",
+ new ArrayList());
+ ((StructureNode)stack.peek()).addChild(peNode);
+ stack.push(peNode);
+ return true;
+ }
+ public void endVisit(FieldDeclaration fieldDeclaration, MethodScope scope) {
+ stack.pop();
+ }
+
+
+// public boolean visit(ImportReference importRef, CompilationUnitScope scope) {
+// ProgramElementNode peNode = new ProgramElementNode(
+// new String(importRef.toString()),
+// ProgramElementNode.Kind.,
+// makeLocation(importRef),
+// 0,
+// "",
+// new ArrayList());
+// ((StructureNode)stack.peek()).addChild(0, peNode);
+// stack.push(peNode);
+// return true;
+// }
+// public void endVisit(ImportReference importRef,CompilationUnitScope scope) {
+// stack.pop();
+// }
+
+ public boolean visit(ConstructorDeclaration constructorDeclaration, ClassScope scope) {
+ if (constructorDeclaration.isDefaultConstructor) {
+ stack.push(null); // a little wierd but does the job
+ return true;
+ }
+ ProgramElementNode peNode = new ProgramElementNode(
+ new String(constructorDeclaration.selector),
+ ProgramElementNode.Kind.CONSTRUCTOR,
+ makeLocation(constructorDeclaration),
+ constructorDeclaration.modifiers,
+ "",
+ new ArrayList());
+ ((StructureNode)stack.peek()).addChild(peNode);
+ stack.push(peNode);
+ return true;
+ }
+ public void endVisit(ConstructorDeclaration constructorDeclaration, ClassScope scope) {
+ stack.pop();
+ }
+
+// public boolean visit(Clinit clinit, ClassScope scope) {
+// ProgramElementNode peNode = new ProgramElementNode(
+// "<clinit>",
+// ProgramElementNode.Kind.INITIALIZER,
+// makeLocation(clinit),
+// clinit.modifiers,
+// "",
+// new ArrayList());
+// ((StructureNode)stack.peek()).addChild(peNode);
+// stack.push(peNode);
+// return false;
+// }
+// public void endVisit(Clinit clinit, ClassScope scope) {
+// stack.pop();
+// }
+
+ /** This method works-around an odd traverse implementation on Initializer
+ */
+ private Initializer inInitializer = null;
+ public boolean visit(Initializer initializer, MethodScope scope) {
+ if (initializer == inInitializer) return false;
+ inInitializer = initializer;
+
+ ProgramElementNode peNode = new ProgramElementNode(
+ "...",
+ ProgramElementNode.Kind.INITIALIZER,
+ makeLocation(initializer),
+ initializer.modifiers,
+ "",
+ new ArrayList());
+ ((StructureNode)stack.peek()).addChild(peNode);
+ stack.push(peNode);
+ initializer.block.traverse(this, scope);
+ stack.pop();
+ return false;
+ }
+
+ // ??? handle non-existant files
+ private ISourceLocation makeLocation(AstNode node) {
+ String fileName = new String(currCompilationResult.getFileName());
+ int line = ProblemHandler.searchLineNumber(
+ currCompilationResult.lineSeparatorPositions,
+ node.sourceStart);
+ return new SourceLocation(new File(fileName), line);
+ }
+
+ // !!! move or replace
+ private String translateAdviceName(String label) {
+ if (label.indexOf("before") != -1) return "before";
+ if (label.indexOf("returning") != -1) return "after returning";
+ if (label.indexOf("after") != -1) return "after";
+ if (label.indexOf("around") != -1) return "around";
+ else return "<advice>";
+ }
+
+ // !!! move or replace
+ private String translateDeclareName(String name) {
+ int colonIndex = name.indexOf(":");
+ if (colonIndex != -1) {
+ return name.substring(0, colonIndex);
+ } else {
+ return name;
+ }
+ }
+
+ // !!! move or replace
+ private String translateInterTypeDecName(String name) {
+ int index = name.lastIndexOf('$');
+ if (index != -1) {
+ return name.substring(index+1);
+ } else {
+ return name;
+ }
+ }
+
+}
diff --git a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/ClassFileCache.java b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/ClassFileCache.java
new file mode 100644
index 000000000..7f06461cf
--- /dev/null
+++ b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/ClassFileCache.java
@@ -0,0 +1,184 @@
+/* *******************************************************************
+ * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC).
+ * All rights reserved.
+ * This program and the accompanying materials are made available
+ * under the terms of the Common Public License v1.0
+ * which accompanies this distribution and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * Xerox/PARC initial implementation
+ * ******************************************************************/
+
+
+package org.aspectj.ajdt.internal.core.builder;
+
+
+import java.util.*;
+
+import org.aspectj.bridge.IMessageHandler;
+import org.aspectj.workbench.resources.AbstractContainer;
+import org.eclipse.core.resources.*;
+import org.eclipse.core.runtime.*;
+
+public class ClassFileCache extends AbstractContainer {
+
+ private IContainer container;
+ private Map cache = new HashMap();
+ private IMessageHandler handler;
+ private Map/*IPath->ClassFileCacheFolder*/ folders = new HashMap();
+
+ public ClassFileCache(IContainer container, IMessageHandler handler) {
+// super(container);
+ this.container = container;
+ this.handler = handler;
+ try {
+ getFolder(new Path("")).create(true, true, null);
+ } catch (CoreException e) {
+ throw new RuntimeException("can't happen");
+ }
+ }
+
+ private Object makeKey(IPath path) {
+ return path.toString(); //??? make sure this is stable
+ }
+
+ public boolean exists(IPath path) {
+ if (folders.keySet().contains(makeKey(path))) {
+ return getFolder(path).exists();
+ } else {
+ return getFile(path).exists(); //??? what if this is called for a folder
+ }
+ }
+
+ public IFile getFile(IPath path) {
+ EclipseUnwovenClassFile cachedFile = (EclipseUnwovenClassFile)cache.get(makeKey(path));
+ if (cachedFile == null) {
+ cachedFile = new EclipseUnwovenClassFile(container.getFile(path), handler);
+ cache.put(makeKey(path), cachedFile);
+ }
+
+ return cachedFile.getFile();
+ }
+
+ public IFolder getFolder(IPath path) {
+ //??? too naive
+ ClassFileCacheFolder folder = (ClassFileCacheFolder)folders.get(makeKey(path));
+ if (folder == null) {
+ folder = new ClassFileCacheFolder(this, path, container.getFolder(path));
+ folders.put(makeKey(path), folder);
+ }
+ return folder;
+ }
+
+ //XXX this doesn't include folders, is that okay?
+ public IResource[] members() throws CoreException {
+ List ret = new ArrayList();
+ for (Iterator i = cache.values().iterator(); i.hasNext(); ) {
+ EclipseUnwovenClassFile cachedFile = (EclipseUnwovenClassFile)i.next();
+ ret.add(cachedFile.getFile());
+ }
+ return (IResource[])ret.toArray(new IResource[ret.size()]);
+ }
+
+ // extra methods for incremental use
+ public void resetIncrementalInfo() {
+ for (Iterator i = cache.values().iterator(); i.hasNext(); ) {
+ EclipseUnwovenClassFile cachedFile = (EclipseUnwovenClassFile)i.next();
+ DeferredWriteFile file = (DeferredWriteFile)cachedFile.getFile();
+ file.setDirty(false);
+ }
+ }
+
+ public List getDeleted() {
+ List ret = new ArrayList();
+ for (Iterator i = cache.values().iterator(); i.hasNext(); ) {
+ EclipseUnwovenClassFile cachedFile = (EclipseUnwovenClassFile)i.next();
+ DeferredWriteFile file = (DeferredWriteFile)cachedFile.getFile();
+ if (file.isDirty() && !file.exists()) {
+ ret.add(cachedFile);
+ }
+ }
+ return ret;
+ }
+
+ public List getAddedOrChanged() {
+ List ret = new ArrayList();
+ for (Iterator i = cache.values().iterator(); i.hasNext(); ) {
+ EclipseUnwovenClassFile cachedFile = (EclipseUnwovenClassFile)i.next();
+ DeferredWriteFile file = (DeferredWriteFile)cachedFile.getFile();
+ if (file.isDirty() && file.exists()) {
+ ret.add(cachedFile);
+ }
+ }
+ return ret;
+ }
+
+
+ public IResource findMember(IPath path) {
+ throw new RuntimeException("unimplemented");
+ }
+
+ public void copy(
+ IPath destination,
+ boolean force,
+ IProgressMonitor monitor)
+ throws CoreException {
+ throw new RuntimeException("unimplemented");
+ }
+
+ public void delete(boolean force, IProgressMonitor monitor)
+ throws CoreException {
+ throw new RuntimeException("unimplemented");
+ }
+
+ public boolean exists() {
+ return true;
+ }
+
+
+ public IPath getFullPath() {
+ return container.getFullPath();
+ }
+
+ public IPath getLocation() {
+ return container.getLocation();
+ }
+
+ public long getModificationStamp() {
+ throw new RuntimeException("unimplemented");
+ }
+
+ public String getName() {
+ return container.getName();
+ }
+
+ public IContainer getParent() {
+ return null;
+ }
+
+ public int getType() {
+ return IResource.FOLDER;
+ }
+
+ public boolean isDerived() {
+ return true;
+ }
+ public void setDerived(boolean isDerived) {
+ if (isDerived) return;
+ throw new RuntimeException("unimplemented");
+ }
+
+ public boolean isReadOnly() {
+ return false;
+ }
+
+ public void setReadOnly(boolean readOnly) {
+ throw new RuntimeException("unimplemented");
+ }
+
+ public void touch(IProgressMonitor monitor) throws CoreException {
+ throw new RuntimeException("unimplemented");
+ }
+
+}
diff --git a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/ClassFileCacheFolder.java b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/ClassFileCacheFolder.java
new file mode 100644
index 000000000..52eae60da
--- /dev/null
+++ b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/ClassFileCacheFolder.java
@@ -0,0 +1,140 @@
+/* *******************************************************************
+ * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC).
+ * All rights reserved.
+ * This program and the accompanying materials are made available
+ * under the terms of the Common Public License v1.0
+ * which accompanies this distribution and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * Xerox/PARC initial implementation
+ * ******************************************************************/
+
+
+package org.aspectj.ajdt.internal.core.builder;
+
+import org.aspectj.workbench.resources.AbstractFolder;
+import org.eclipse.core.resources.*;
+import org.eclipse.core.runtime.*;
+
+public class ClassFileCacheFolder extends AbstractFolder {
+ ClassFileCache parent;
+ IPath myPath;
+ boolean exists;
+ IFolder folder;
+
+ public ClassFileCacheFolder(ClassFileCache parent, IPath path, IFolder folder) {
+ this.folder = folder;
+ this.myPath = path;
+ this.parent = parent;
+ }
+
+
+ public IFile getFile(IPath path) {
+ return parent.getFile(myPath.append(path));
+ }
+
+ public IFolder getFolder(IPath path) {
+ return parent.getFolder(myPath.append(path));
+ }
+
+ public IResource[] members() throws CoreException {
+ throw new RuntimeException("unimplemented");
+ }
+
+
+ public void create(boolean force, boolean local, IProgressMonitor monitor)
+ throws CoreException
+ {
+ exists = true;
+ //XXX is this sufficient
+// super.create(force, local, monitor);
+ }
+
+ public boolean exists() {
+ return exists;
+ }
+
+ public boolean exists(IPath path) {
+ if (exists) {
+ return parent.exists(myPath.append(path));
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * @see org.eclipse.core.resources.IResource#delete(boolean, IProgressMonitor)
+ */
+ public void delete(boolean force, IProgressMonitor monitor)
+ throws CoreException {
+ exists = false;
+ }
+
+
+ public void move(
+ IPath destination,
+ boolean force,
+ boolean keepHistory,
+ IProgressMonitor monitor)
+ throws CoreException {
+ throw new RuntimeException("not implemented");
+ }
+
+ public IResource findMember(IPath path) {
+ throw new RuntimeException("unimplemented");
+ }
+
+ public void copy(
+ IPath destination,
+ boolean force,
+ IProgressMonitor monitor)
+ throws CoreException {
+ throw new RuntimeException("unimplemented");
+ }
+
+ public IPath getFullPath() {
+ throw new RuntimeException("unimplemented");
+ }
+
+ public IPath getLocation() {
+ throw new RuntimeException("unimplemented");
+ }
+
+ public long getModificationStamp() {
+ throw new RuntimeException("unimplemented");
+ }
+
+ public String getName() {
+ throw new RuntimeException("unimplemented");
+ }
+
+ public IContainer getParent() {
+ throw new RuntimeException("unimplemented");
+ }
+
+ public int getType() {
+ return IResource.FOLDER;
+ }
+
+ public boolean isDerived() {
+ return true;
+ }
+ public void setDerived(boolean isDerived) {
+ if (isDerived) return;
+ throw new RuntimeException("unimplemented");
+ }
+
+ public boolean isReadOnly() {
+ throw new RuntimeException("unimplemented");
+ }
+
+ public void setReadOnly(boolean readOnly) {
+ throw new RuntimeException("unimplemented");
+ }
+
+ public void touch(IProgressMonitor monitor) throws CoreException {
+ throw new RuntimeException("unimplemented");
+ }
+
+}
diff --git a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/ClasspathContainer.java b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/ClasspathContainer.java
new file mode 100644
index 000000000..08d4e8bee
--- /dev/null
+++ b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/ClasspathContainer.java
@@ -0,0 +1,81 @@
+/* *******************************************************************
+ * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC).
+ * All rights reserved.
+ * This program and the accompanying materials are made available
+ * under the terms of the Common Public License v1.0
+ * which accompanies this distribution and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * Xerox/PARC initial implementation
+ * ******************************************************************/
+
+
+package org.aspectj.ajdt.internal.core.builder;
+
+import org.eclipse.jdt.internal.core.builder.*;
+import org.aspectj.util.FileUtil;
+import org.eclipse.core.resources.*;
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.runtime.*;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileReader;
+import org.eclipse.jdt.internal.compiler.env.NameEnvironmentAnswer;
+import org.eclipse.jdt.internal.compiler.util.Util;
+
+import java.io.*;
+
+class ClasspathContainer extends ClasspathLocation {
+
+ IContainer container;
+
+ ClasspathContainer(IContainer container) {
+ this.container = container;
+ }
+
+ public void cleanup() {
+ }
+
+ public boolean equals(Object o) {
+ if (this == o)
+ return true;
+ if (!(o instanceof ClasspathContainer))
+ return false;
+
+ return container.equals(((ClasspathContainer) o).container);
+ }
+
+ public NameEnvironmentAnswer findClass(
+ String binaryFileName,
+ String qualifiedPackageName,
+ String qualifiedBinaryFileName)
+ {
+ IFile file = container.getFile(makePath(qualifiedBinaryFileName));
+ if (!file.exists()) return null;
+
+ try {
+ byte[] classFileBytes = Util.getInputStreamAsByteArray(file.getContents(), -1);
+ ClassFileReader reader =
+ new ClassFileReader(classFileBytes, file.getFullPath().toString().toCharArray());
+ return new NameEnvironmentAnswer(reader);
+ } catch (Exception e) {
+ } // treat as if class file is missing
+ return null;
+ }
+
+ public boolean isPackage(String qualifiedPackageName) {
+ return container.getFolder(makePath(qualifiedPackageName)).exists();
+ }
+
+ private IPath makePath(String qualifiedPackageName) {
+ return new Path(qualifiedPackageName);
+ }
+
+
+ public void reset() {
+ }
+
+ public String toString() {
+ return "Container classpath directory " + container; //$NON-NLS-1$
+ }
+}
diff --git a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/ClasspathSourcefiles.java b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/ClasspathSourcefiles.java
new file mode 100644
index 000000000..7bf742b6d
--- /dev/null
+++ b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/ClasspathSourcefiles.java
@@ -0,0 +1,42 @@
+/* *******************************************************************
+ * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC).
+ * All rights reserved.
+ * This program and the accompanying materials are made available
+ * under the terms of the Common Public License v1.0
+ * which accompanies this distribution and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * Xerox/PARC initial implementation
+ * ******************************************************************/
+
+
+package org.aspectj.ajdt.internal.core.builder;
+
+import java.util.List;
+
+import org.eclipse.jdt.internal.compiler.env.NameEnvironmentAnswer;
+import org.eclipse.jdt.internal.core.builder.ClasspathLocation;
+
+public class ClasspathSourcefiles extends ClasspathLocation {
+ private List/*File*/ files;
+ private String[] knownFileNames;
+
+ public ClasspathSourcefiles(List files) {
+ this.files = files;
+ }
+
+ //XXX this doesn't always work
+ public NameEnvironmentAnswer findClass(
+ String binaryFileName,
+ String qualifiedPackageName,
+ String qualifiedBinaryFileName)
+ {
+ return null;
+ }
+
+ public boolean isPackage(String qualifiedPackageName) {
+ return false;
+ }
+
+}
diff --git a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/CommandLineResourceDelta.java b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/CommandLineResourceDelta.java
new file mode 100644
index 000000000..79e48ff53
--- /dev/null
+++ b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/CommandLineResourceDelta.java
@@ -0,0 +1,82 @@
+/* *******************************************************************
+ * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC).
+ * All rights reserved.
+ * This program and the accompanying materials are made available
+ * under the terms of the Common Public License v1.0
+ * which accompanies this distribution and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * Xerox/PARC initial implementation
+ * ******************************************************************/
+
+
+package org.aspectj.ajdt.internal.core.builder;
+
+import org.apache.bcel.generic.RETURN;
+import org.aspectj.workbench.resources.FilesystemFile;
+import org.eclipse.core.internal.events.*;
+import org.eclipse.core.internal.resources.ResourceInfo;
+import org.eclipse.core.resources.*;
+import org.eclipse.core.resources.IResourceDelta;
+import org.eclipse.core.runtime.IPath;
+
+public class CommandLineResourceDelta extends ResourceDelta {
+
+ private int kind;
+ private IResource resource;
+
+ public CommandLineResourceDelta(IResource resource) {
+ super(resource.getFullPath(), null);
+ setNewInfo(new ResourceInfo());
+ setOldInfo(new ResourceInfo());
+ children = new ResourceDelta[0];
+ this.resource = resource;
+ }
+
+ public void setKind(int kind) {
+ this.kind = kind;
+ if (kind == IResourceDelta.CHANGED) {
+ status |= IResourceDelta.CONTENT; // ??? is this alwyas right
+ }
+ }
+
+ public int getKind() {
+ return kind;
+ }
+
+ public void setChildren(IResourceDelta[] children) {
+ this.children = children;
+ }
+
+ public IResource getResource() {
+ return resource;
+ }
+
+ public String toString() {
+ return super.toDeepDebugString();
+// StringBuffer s = new StringBuffer();
+// s.append("ResourceDelta(");
+// s.append("path: " + path);
+// s.append(",");
+// s.append("kind: ");
+// s.append(kind);
+// if (children != null) {
+// for (int i = 0; i < children.length; i++) {
+// s.append(children[i].toString());
+// }
+// }
+// s.append(")");
+// return s.toString();
+ }
+ public IResourceDelta findMember(IPath path) {
+ if (resource.getFullPath().equals(path)) {
+ return this;
+ } else {
+ for (int i = 0; i < children.length; i++) {
+ return children[i].findMember(path);
+ }
+ }
+ return null;
+ }
+}
diff --git a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/DeferredWriteFile.java b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/DeferredWriteFile.java
new file mode 100644
index 000000000..8f7fd3f19
--- /dev/null
+++ b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/DeferredWriteFile.java
@@ -0,0 +1,179 @@
+/* *******************************************************************
+ * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC).
+ * All rights reserved.
+ * This program and the accompanying materials are made available
+ * under the terms of the Common Public License v1.0
+ * which accompanies this distribution and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * Xerox/PARC initial implementation
+ * ******************************************************************/
+
+
+package org.aspectj.ajdt.internal.core.builder;
+
+import java.io.*;
+
+import org.aspectj.workbench.resources.AbstractFile;
+import org.eclipse.core.resources.*;
+import org.eclipse.core.runtime.*;
+import org.eclipse.jdt.core.*;
+import org.eclipse.jdt.internal.compiler.util.Util;
+
+public class DeferredWriteFile extends AbstractFile {
+
+ private IFile file;
+ private byte[] unwovenBytes;
+ private boolean dirty = false;
+
+ public DeferredWriteFile(IFile file) {
+ this.file = file;
+ }
+
+ public byte[] getUnwovenBytes() {
+ return unwovenBytes;
+ }
+
+ public void writeInnerWovenBytes(String innerName, byte[] bytes) throws CoreException {
+ IContainer folder = file.getParent();
+ IFile innerFile = folder.getFile(new Path(makeInnerName(innerName)));
+ innerFile.create(new ByteArrayInputStream(bytes), true, null);
+
+ }
+
+ private String makeInnerName(String innerName) {
+ String filename = file.getName();
+ String prefix = filename.substring(0, filename.length()-6); // strip the .class
+ return prefix + "$" + innerName + ".class";
+ }
+
+
+
+ public void writeWovenBytes(byte[] wovenBytes) throws CoreException {
+ file.create(new ByteArrayInputStream(wovenBytes), true, null);
+ }
+
+ public void create(
+ InputStream source,
+ boolean force,
+ IProgressMonitor monitor)
+ throws CoreException
+ {
+ try {
+ dirty = true;
+ unwovenBytes =
+ Util.getInputStreamAsByteArray(source, -1);
+ //??? understand this betterwriteWovenBytes(unwovenBytes);
+ } catch (IOException e) {
+ throw new JavaModelException(
+ e,
+ IJavaModelStatusConstants.IO_EXCEPTION);
+ }
+ }
+
+ public void delete(boolean force, IProgressMonitor monitor)
+ throws CoreException {
+ //System.out.println("delete: " + this);
+ unwovenBytes = null;
+ dirty = true;
+ }
+
+ public InputStream getContents(boolean force) throws CoreException {
+ return new ByteArrayInputStream(unwovenBytes);
+ }
+
+
+ public boolean exists() {
+ return unwovenBytes != null;
+ }
+
+ public boolean isDirty() {
+ return dirty;
+ }
+
+ public void setDirty(boolean dirty) {
+ this.dirty = dirty;
+ }
+
+ public void deleteRealFile() throws CoreException {
+ file.delete(true, null);
+ }
+
+ public String toString() {
+ return "DeferredWriteFile(" + getName() + ", " + exists() + ")";
+ }
+
+ public IContainer getParent() {
+ throw new RuntimeException("unimplemented");
+ }
+
+ public int getEncoding() throws CoreException {
+ throw new RuntimeException("unimplemented");
+ }
+
+ public void setContents(
+ InputStream source,
+ boolean force,
+ boolean keepHistory,
+ IProgressMonitor monitor)
+ throws CoreException {
+ throw new RuntimeException("unimplemented");
+ }
+
+ public void copy(
+ IPath destination,
+ boolean force,
+ IProgressMonitor monitor)
+ throws CoreException {
+ throw new RuntimeException("unimplemented");
+ }
+
+ public String getFileExtension() {
+ return file.getFileExtension();
+ }
+
+ public IPath getFullPath() {
+ return file.getFullPath();
+ }
+
+ public IPath getLocation() {
+ return file.getLocation();
+ }
+
+ public long getModificationStamp() {
+ throw new RuntimeException("unimplemented");
+ }
+
+ public String getName() {
+ return file.getName();
+ }
+
+ public int getType() {
+ return IResource.FILE;
+ }
+
+ public boolean isDerived() {
+ return true;
+ }
+
+ public void setDerived(boolean isDerived) {
+ if (isDerived) return;
+ throw new RuntimeException("unimplemented");
+ }
+
+ public boolean isReadOnly() {
+ return false;
+ }
+
+ public void setReadOnly(boolean readOnly) {
+ throw new RuntimeException("unimplemented");
+ }
+
+ public void touch(IProgressMonitor monitor) throws CoreException {
+ throw new RuntimeException("unimplemented");
+ }
+
+
+
+}
diff --git a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/EclipseAdapterUtils.java b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/EclipseAdapterUtils.java
new file mode 100644
index 000000000..c19efc2e7
--- /dev/null
+++ b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/EclipseAdapterUtils.java
@@ -0,0 +1,141 @@
+/* *******************************************************************
+ * Copyright (c) 1999-2001 Xerox Corporation,
+ * 2002 Palo Alto Research Center, Incorporated (PARC).
+ * All rights reserved.
+ * This program and the accompanying materials are made available
+ * under the terms of the Common Public License v1.0
+ * which accompanies this distribution and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * Xerox/PARC initial implementation
+ * ******************************************************************/
+
+package org.aspectj.ajdt.internal.core.builder;
+
+import org.aspectj.bridge.IMessage;
+import org.aspectj.bridge.ISourceLocation;
+import org.aspectj.bridge.Message;
+import org.aspectj.bridge.SourceLocation;
+import org.aspectj.util.LangUtil;
+import org.eclipse.jdt.core.compiler.IProblem;
+import org.eclipse.jdt.internal.compiler.env.ICompilationUnit;
+import org.eclipse.jdt.internal.compiler.util.Util;
+
+import java.io.File;
+
+/**
+ *
+ */
+public class EclipseAdapterUtils {
+
+ //XXX some cut-and-paste from eclipse sources
+ public static String makeLocationContext(ICompilationUnit compilationUnit, IProblem problem) {
+ //extra from the source the innacurate token
+ //and "highlight" it using some underneath ^^^^^
+ //put some context around too.
+
+ //this code assumes that the font used in the console is fixed size
+
+ //sanity .....
+ int startPosition = problem.getSourceStart();
+ int endPosition = problem.getSourceEnd();
+
+ if ((startPosition > endPosition)
+ || ((startPosition <= 0) && (endPosition <= 0)))
+ return Util.bind("problem.noSourceInformation"); //$NON-NLS-1$
+
+ final char SPACE = '\u0020';
+ final char MARK = '^';
+ final char TAB = '\t';
+ char[] source = compilationUnit.getContents();
+ //the next code tries to underline the token.....
+ //it assumes (for a good display) that token source does not
+ //contain any \r \n. This is false on statements !
+ //(the code still works but the display is not optimal !)
+
+ //compute the how-much-char we are displaying around the inaccurate token
+ int begin = startPosition >= source.length ? source.length - 1 : startPosition;
+ int relativeStart = 0;
+ int end = endPosition >= source.length ? source.length - 1 : endPosition;
+ int relativeEnd = 0;
+ label : for (relativeStart = 0;; relativeStart++) {
+ if (begin == 0)
+ break label;
+ if ((source[begin - 1] == '\n') || (source[begin - 1] == '\r'))
+ break label;
+ begin--;
+ }
+ label : for (relativeEnd = 0;; relativeEnd++) {
+ if ((end + 1) >= source.length)
+ break label;
+ if ((source[end + 1] == '\r') || (source[end + 1] == '\n')) {
+ break label;
+ }
+ end++;
+ }
+ //extract the message form the source
+ char[] extract = new char[end - begin + 1];
+ System.arraycopy(source, begin, extract, 0, extract.length);
+ char c;
+ //remove all SPACE and TAB that begin the error message...
+ int trimLeftIndex = 0;
+ while (((c = extract[trimLeftIndex++]) == TAB) || (c == SPACE)) {
+ };
+ System.arraycopy(
+ extract,
+ trimLeftIndex - 1,
+ extract = new char[extract.length - trimLeftIndex + 1],
+ 0,
+ extract.length);
+ relativeStart -= trimLeftIndex;
+ //buffer spaces and tabs in order to reach the error position
+ int pos = 0;
+ char[] underneath = new char[extract.length]; // can't be bigger
+ for (int i = 0; i <= relativeStart; i++) {
+ if (extract[i] == TAB) {
+ underneath[pos++] = TAB;
+ } else {
+ underneath[pos++] = SPACE;
+ }
+ }
+ //mark the error position
+ for (int i = startPosition;
+ i <= (endPosition >= source.length ? source.length - 1 : endPosition);
+ i++)
+ underneath[pos++] = MARK;
+ //resize underneathto remove 'null' chars
+ System.arraycopy(underneath, 0, underneath = new char[pos], 0, pos);
+
+ return new String(extract) + "\n" + new String(underneath); //$NON-NLS-2$ //$NON-NLS-1$
+ }
+
+ public static ISourceLocation makeSourceLocation(ICompilationUnit unit, IProblem problem) {
+ int line = problem.getSourceLineNumber();
+ File file = new File(new String(problem.getOriginatingFileName()));
+ return new SourceLocation(file, line, line, 0);
+ }
+
+ /** This renders entire message text, but also sets up source location */
+ public static IMessage makeMessage(ICompilationUnit unit, IProblem problem) {
+ //??? would like to know the column as well as line
+ //??? and also should generate highlighting info
+ ISourceLocation sourceLocation = makeSourceLocation(unit, problem);
+
+ String locationContext = makeLocationContext(unit, problem);
+ StringBuffer mssg = new StringBuffer();
+
+ mssg.append(problem.getOriginatingFileName());
+ mssg.append(":" + problem.getSourceLineNumber());
+ mssg.append(": ");
+ mssg.append(problem.getMessage());
+ mssg.append(LangUtil.EOL);
+ mssg.append(locationContext);
+
+ return new Message(mssg.toString(), sourceLocation, problem.isError());
+ }
+
+ private EclipseAdapterUtils() {
+ }
+
+}
diff --git a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/EclipseMessageHandler.java b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/EclipseMessageHandler.java
new file mode 100644
index 000000000..4d77254db
--- /dev/null
+++ b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/EclipseMessageHandler.java
@@ -0,0 +1,190 @@
+/* *******************************************************************
+ * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC).
+ * All rights reserved.
+ * This program and the accompanying materials are made available
+ * under the terms of the Common Public License v1.0
+ * which accompanies this distribution and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * Xerox/PARC initial implementation
+ * ******************************************************************/
+
+
+package org.aspectj.ajdt.internal.core.builder;
+
+import java.io.*;
+
+import org.aspectj.bridge.*;
+import org.eclipse.jdt.core.compiler.*;
+import org.eclipse.jdt.internal.compiler.env.*;
+import org.eclipse.jdt.internal.compiler.problem.*;
+import org.eclipse.jdt.internal.compiler.util.*;
+
+/** @deprecated EclipseMessageAdapter */
+public class EclipseMessageHandler { // implements IMessageHandler {
+ IMessageHandler handler;
+ private int errorCount = 0;
+
+ private EclipseMessageHandler(IMessageHandler handler) {
+ super();
+ this.handler = handler;
+ }
+}
+
+// private IMessage makeMessage(ICompilationUnit unit, IProblem problem) {
+// //??? would like to know the column as well as line
+// //??? and also should generate highlighting info
+// int line = problem.getSourceLineNumber();
+// SourceLocation loc =
+// new SourceLocation(new File(new String(problem.getOriginatingFileName())),
+// line, line, 0);
+//
+// String locationContext = makeLocationContext(unit, problem);
+//// System.err.println("(" + locationContext + ")");
+//
+// return new CommandLineMessage(problem.getMessage(),
+// problem.isError() ? IMessage.ERROR : IMessage.WARNING,
+// null, loc, locationContext);
+// }
+//
+//
+// //XXX some cut-and-paste from eclipse sources
+// public String makeLocationContext(ICompilationUnit compilationUnit, IProblem problem) {
+// //extra from the source the innacurate token
+// //and "highlight" it using some underneath ^^^^^
+// //put some context around too.
+//
+// //this code assumes that the font used in the console is fixed size
+//
+// //sanity .....
+// int startPosition = problem.getSourceStart();
+// int endPosition = problem.getSourceEnd();
+//
+// if ((startPosition > endPosition)
+// || ((startPosition <= 0) && (endPosition <= 0)))
+// return Util.bind("problem.noSourceInformation"); //$NON-NLS-1$
+//
+// final char SPACE = '\u0020';
+// final char MARK = '^';
+// final char TAB = '\t';
+// char[] source = compilationUnit.getContents();
+// //the next code tries to underline the token.....
+// //it assumes (for a good display) that token source does not
+// //contain any \r \n. This is false on statements !
+// //(the code still works but the display is not optimal !)
+//
+// //compute the how-much-char we are displaying around the inaccurate token
+// int begin = startPosition >= source.length ? source.length - 1 : startPosition;
+// int relativeStart = 0;
+// int end = endPosition >= source.length ? source.length - 1 : endPosition;
+// int relativeEnd = 0;
+// label : for (relativeStart = 0;; relativeStart++) {
+// if (begin == 0)
+// break label;
+// if ((source[begin - 1] == '\n') || (source[begin - 1] == '\r'))
+// break label;
+// begin--;
+// }
+// label : for (relativeEnd = 0;; relativeEnd++) {
+// if ((end + 1) >= source.length)
+// break label;
+// if ((source[end + 1] == '\r') || (source[end + 1] == '\n')) {
+// break label;
+// }
+// end++;
+// }
+// //extract the message form the source
+// char[] extract = new char[end - begin + 1];
+// System.arraycopy(source, begin, extract, 0, extract.length);
+// char c;
+// //remove all SPACE and TAB that begin the error message...
+// int trimLeftIndex = 0;
+// while (((c = extract[trimLeftIndex++]) == TAB) || (c == SPACE)) {
+// };
+// System.arraycopy(
+// extract,
+// trimLeftIndex - 1,
+// extract = new char[extract.length - trimLeftIndex + 1],
+// 0,
+// extract.length);
+// relativeStart -= trimLeftIndex;
+// //buffer spaces and tabs in order to reach the error position
+// int pos = 0;
+// char[] underneath = new char[extract.length]; // can't be bigger
+// for (int i = 0; i <= relativeStart; i++) {
+// if (extract[i] == TAB) {
+// underneath[pos++] = TAB;
+// } else {
+// underneath[pos++] = SPACE;
+// }
+// }
+// //mark the error position
+// for (int i = startPosition;
+// i <= (endPosition >= source.length ? source.length - 1 : endPosition);
+// i++)
+// underneath[pos++] = MARK;
+// //resize underneathto remove 'null' chars
+// System.arraycopy(underneath, 0, underneath = new char[pos], 0, pos);
+//
+// return new String(extract) + "\n" + new String(underneath); //$NON-NLS-2$ //$NON-NLS-1$
+// }
+//
+//
+// public boolean handleProblem(ICompilationUnit unit, IProblem problem) {
+// return handleMessage(makeMessage(unit, problem));
+// }
+//
+// public boolean handleThrowable(Throwable t) {
+// return handleThrowable(t.toString(), t);
+// }
+//
+// public boolean handleThrowable(String message, Throwable t) {
+// return handleMessage(new Message(message, IMessage.ERROR, t, null));
+// }
+//
+// public boolean handleMessage(IMessage message) throws AbortException {
+// if (message.getKind() == Message.ERROR) errorCount++;
+//
+// //XXX Mik and Jim will figure out what this is doing
+// if (message.getKind() == Message.ERROR || message.getKind() == Message.WARNING) {
+// ISourceLocation loc = message.getISourceLocation();
+// String msg = message.getMessage();
+// if (loc == null) {
+// System.err.println(msg);
+// } else {
+// StringBuffer buf = new StringBuffer();
+// buf.append(loc.getSourceFile().getPath() + ":" + loc.getLine());
+// if (loc.getColumn() != -1) {
+// buf.append(":" + loc.getColumn());
+// }
+// buf.append(": ");
+// buf.append(msg);
+// buf.append("\n");
+// if (message instanceof CommandLineMessage) {
+// buf.append(((CommandLineMessage)message).getLocationContext());
+// }
+// System.err.println(buf.toString());
+// }
+//
+// }
+// return handler.handleMessage(message);
+// }
+//
+// public boolean isIgnoring(IMessage.Kind kind) {
+// return handler.isIgnoring(kind);
+// }
+//
+// public boolean handleError(String string) {
+// return handleMessage(new Message(string, IMessage.ERROR, null, null));
+// }
+//
+// public int getErrorCount() {
+// return errorCount;
+// }
+//
+// public void resetErrorCount() {
+// this.errorCount = 0;
+// }
+
+
diff --git a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/EclipseSourceContext.java b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/EclipseSourceContext.java
new file mode 100644
index 000000000..e398a9d84
--- /dev/null
+++ b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/EclipseSourceContext.java
@@ -0,0 +1,37 @@
+/* *******************************************************************
+ * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC).
+ * All rights reserved.
+ * This program and the accompanying materials are made available
+ * under the terms of the Common Public License v1.0
+ * which accompanies this distribution and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * Xerox/PARC initial implementation
+ * ******************************************************************/
+
+
+package org.aspectj.ajdt.internal.core.builder;
+
+import org.aspectj.ajdt.internal.compiler.lookup.EclipseSourceLocation;
+import org.aspectj.bridge.ISourceLocation;
+import org.aspectj.weaver.*;
+import org.aspectj.weaver.ISourceContext;
+import org.eclipse.jdt.internal.compiler.CompilationResult;
+
+
+
+public class EclipseSourceContext implements ISourceContext {
+
+ CompilationResult result;
+
+ public EclipseSourceContext(CompilationResult result) {
+ this.result = result;
+ }
+
+
+ public ISourceLocation makeSourceLocation(IHasPosition position) {
+ return new EclipseSourceLocation(result, position.getStart(), position.getEnd());
+ }
+
+}
diff --git a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/EclipseUnwovenClassFile.java b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/EclipseUnwovenClassFile.java
new file mode 100644
index 000000000..a3008b49d
--- /dev/null
+++ b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/EclipseUnwovenClassFile.java
@@ -0,0 +1,113 @@
+/* *******************************************************************
+ * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC).
+ * All rights reserved.
+ * This program and the accompanying materials are made available
+ * under the terms of the Common Public License v1.0
+ * which accompanies this distribution and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * Xerox/PARC initial implementation
+ * ******************************************************************/
+
+
+package org.aspectj.ajdt.internal.core.builder;
+
+import java.io.IOException;
+import java.util.*;
+import java.util.List;
+
+import org.aspectj.weaver.bcel.UnwovenClassFile;
+import org.aspectj.bridge.IMessage;
+import org.aspectj.bridge.IMessageHandler;
+import org.aspectj.bridge.Message;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.runtime.CoreException;
+import sun.misc.MessageUtils;
+
+public class EclipseUnwovenClassFile extends UnwovenClassFile {
+
+ private DeferredWriteFile file = null;
+ private IMessageHandler handler = null;
+
+ public EclipseUnwovenClassFile(IFile file, IMessageHandler handler) {
+ super(null, null);
+ this.file = new DeferredWriteFile(file);
+ this.handler = handler;
+ }
+
+ public String getFilename() {
+ return getFile().getLocation().toString();
+ }
+
+
+ public IFile getFile() {
+ return file;
+ }
+
+ public void clear() {
+// javaClass = null;
+ }
+
+ public byte[] getBytes() {
+ bytes = file.getUnwovenBytes();
+ return bytes;
+ }
+
+ public void deleteRealFile() throws IOException {
+ try {
+ file.deleteRealFile();
+ } catch (CoreException ce) {
+ throw new RuntimeException("unimplemented");
+ }
+ }
+
+ public UnwovenClassFile makeInnerClassFile(
+ String innerName,
+ byte[] bytes) {
+ throw new RuntimeException("unimplemented");
+ }
+
+ public void writeWovenBytes(byte[] bytes, List childClasses) throws IOException {
+ if (!childClasses.isEmpty()) {
+ writeChildClasses(childClasses);
+ }
+ try {
+ file.writeWovenBytes(bytes);
+ handler.handleMessage(new Message("wrote class file: " + file.getLocation().toFile().getAbsolutePath(), IMessage.INFO, null, null));
+ } catch (CoreException ce) {
+ //XXX more difficult than this
+ throw new IOException(ce.toString());
+ }
+ }
+
+ private void writeChildClasses(List childClasses) throws IOException {
+ //??? we only really need to delete writtenChildClasses whose
+ //??? names aren't in childClasses; however, it's unclear
+ //??? how much that will affect performance
+ //XXXdeleteAllChildClasses();
+
+ //XXXchildClasses.removeAll(writtenChildClasses);
+
+ for (Iterator iter = childClasses.iterator(); iter.hasNext();) {
+ ChildClass childClass = (ChildClass) iter.next();
+ writeChildClassFile(childClass.name, childClass.bytes);
+
+ }
+
+ writtenChildClasses = childClasses;
+
+ }
+
+ private void writeChildClassFile(String innerName, byte[] bytes) throws IOException {
+ try {
+ file.writeInnerWovenBytes(innerName, bytes);
+ //handler.handleMessage(new Message("wrote class file: " + file.getLocation().toFile().getAbsolutePath(), IMessage.INFO, null, null));
+ } catch (CoreException ce) {
+ //XXX more difficult than this
+ throw new IOException(ce.toString());
+ }
+ }
+
+
+}
diff --git a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/EmacsStructureModelManager.java b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/EmacsStructureModelManager.java
new file mode 100644
index 000000000..b0ae3eeeb
--- /dev/null
+++ b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/EmacsStructureModelManager.java
@@ -0,0 +1,217 @@
+/* *******************************************************************
+ * Copyright (c) 1999-2001 Xerox Corporation,
+ * 2002 Palo Alto Research Center, Incorporated (PARC).
+ * All rights reserved.
+ * This program and the accompanying materials are made available
+ * under the terms of the Common Public License v1.0
+ * which accompanies this distribution and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * Xerox/PARC initial implementation
+ * ******************************************************************/
+
+
+package org.aspectj.ajdt.internal.core.builder;
+
+import java.util.*;
+import java.io.*;
+//import org.aspectj.tools.ide.*;
+import org.aspectj.asm.*;
+//import org.aspectj.ajde.compiler.AjdeCompiler;
+
+/**
+ * @author Mik Kersten
+ */
+public class EmacsStructureModelManager {
+
+ private static final String EXTERN_FILE_SUFFIX = ".ajesym";
+
+ public EmacsStructureModelManager() {
+ super();
+ }
+
+ public void externalizeModel() {
+ if (!StructureModelManager.INSTANCE.getStructureModel().isValid()) return;
+
+ try {
+ Set fileSet = StructureModelManager.INSTANCE.getStructureModel().getFileMap().entrySet();
+ for (Iterator it = fileSet.iterator(); it.hasNext(); ) {
+ ProgramElementNode peNode = (ProgramElementNode)((Map.Entry)it.next()).getValue();
+ dumpStructureToFile(peNode);
+ }
+ } catch (IOException ioe) {
+ ioe.printStackTrace();
+ }
+ }
+
+// private void dumpStructureToFile(ProgramElementNode node) throws IOException {
+// String sourceName = node.getSourceLocation().getSourceFilePath();
+// String fileName = sourceName.substring(0, sourceName.lastIndexOf(".")) + EXTERN_FILE_SUFFIX;
+// BufferedWriter writer = new BufferedWriter(new FileWriter(new File(fileName)));
+// new SExpressionPrinter(writer).printDecls(node);
+// writer.flush();
+// }
+
+ private void dumpStructureToFile(ProgramElementNode node) throws IOException {
+ String sourceName = node.getSourceLocation().getSourceFile().getAbsolutePath();
+ String fileName = sourceName.substring(0, sourceName.lastIndexOf(".")) + EXTERN_FILE_SUFFIX;
+ BufferedWriter writer = null;
+ try {
+ writer = new BufferedWriter(new FileWriter(new File(fileName)));
+ new SExpressionPrinter(writer).printDecls(node);
+ writer.flush();
+ } finally {
+ if (writer != null) {
+ try {
+ writer.close();
+ } catch (IOException e) {} // ignore
+ }
+ }
+ }
+
+ /**
+ * This class was not written in an OO style.
+ */
+ private static class SExpressionPrinter {
+
+ private BufferedWriter writer = null;
+
+ public SExpressionPrinter(BufferedWriter writer) {
+ this.writer = writer;
+ }
+
+ private void printDecls(ProgramElementNode node) {
+ print("(");
+ for (Iterator it = node.getChildren().iterator(); it.hasNext(); ) {
+ // this ignores relations on the compile unit
+ Object nodeObject = it.next();
+ if (nodeObject instanceof ProgramElementNode) {
+ ProgramElementNode child = (ProgramElementNode)nodeObject;
+ printDecl(child, true);
+ } else if (nodeObject instanceof LinkNode) {
+ LinkNode child = (LinkNode)nodeObject;
+ printDecl(child.getProgramElementNode(), false);
+ }
+ }
+ print(") ");
+ }
+
+ private void printDecls(RelationNode node) {
+ for (Iterator it = node.getChildren().iterator(); it.hasNext(); ) {
+ // this ignores relations on the compile unit
+ Object nodeObject = it.next();
+ if (nodeObject instanceof LinkNode) {
+ LinkNode child = (LinkNode)nodeObject;
+ if (//!child.getProgramElementNode().getKind().equals("stmnt") &&
+ !child.getProgramElementNode().getKind().equals("<undefined>")) {
+ printDecl(child.getProgramElementNode(), false);
+// printDecl(child.getProgramElementNode(), false);
+ }
+ }
+ }
+ }
+
+ /**
+ * @param structureNode can be a ProgramElementNode or a LinkNode
+ */
+ private void printDecl(ProgramElementNode node, boolean recurse) {
+ if (node == null || node.getSourceLocation() == null) return;
+ String kind = node.getKind().toLowerCase();
+ print("(");
+ print("(" + node.getSourceLocation().getLine() + " . " + node.getSourceLocation().getColumn() + ") ");
+ print("(" + node.getSourceLocation().getLine() + " . " + node.getSourceLocation().getColumn() + ") ");
+ print(kind + " "); //2
+
+ // HACK:
+ String displayName = node.toString().replace('\"', ' ');
+
+ print("\"" + displayName + "\" ");
+ if (node.getSourceLocation().getSourceFile().getAbsolutePath() != null) {
+ print("\"" + fixFilename(node.getSourceLocation().getSourceFile().getAbsolutePath()) + "\""); //4
+ } else {
+ print("nil");
+ }
+ if (node.getSignature() != null) {
+ print("\"" + node.getDeclaringType() + "\" "); //5
+ } else {
+ print("nil");
+ }
+
+ if (!recurse) {
+ print("nil");
+ print("nil");
+ print("nil");
+ } else {
+ print("(");
+ if (node instanceof ProgramElementNode) {
+ java.util.List relations = ((ProgramElementNode)node).getRelations();
+ if (relations != null) {
+ for (Iterator it = relations.iterator(); it.hasNext(); ) {
+ RelationNode relNode = (RelationNode)it.next();
+ if (relNode.getRelation().getAssociationName().equals(AdviceAssociation.NAME) ||
+ relNode.getRelation().getAssociationName().equals(IntroductionAssociation.NAME)) {
+ printDecls(relNode); // 6
+ }
+ }
+ }
+ }
+ print(") ");
+ print("(");
+ print(") ");
+ print("(");
+ Iterator it3 = node.getChildren().iterator();
+ if (it3.hasNext()) {
+ while (it3.hasNext()) {
+ // this ignores relations on the compile unit
+ Object nodeObject = it3.next();
+ if (nodeObject instanceof ProgramElementNode) {
+ ProgramElementNode currNode = (ProgramElementNode)nodeObject;
+ if (//!currNode.isStmntKind() &&
+ !currNode.getKind().equals("<undefined>")) {
+ printDecl(currNode, true);
+ }
+ }
+ }
+ }
+ print(") ");
+ }
+
+ print(node.getKind().equals("class") ? "t " : "nil "); // 9
+// print(node.getKind().equals("introduction") ? "t " : "nil "); // 10
+ print(node.getKind().equals("introduction") ? "nil " : "nil "); // 10
+ print("nil "); // 11
+ print("nil "); // 12
+ print(")");
+ }
+
+ String fixFilename(String filename) {
+ return subst("\\\\", "\\", filename);
+ }
+
+ private void print(String string) {
+ try {
+ writer.write(string + "\n");
+ } catch (IOException ioe) {
+ ioe.printStackTrace();
+ }
+ }
+
+ private String subst(String n, String o, String in) {
+ int pos = in.indexOf(o);
+ if (pos == -1)
+ return in;
+ return in.substring(0, pos) +
+ n +
+ subst(n, o, (in.substring(pos + o.length())));
+ }
+
+ private void lose(Error e) {
+ try {
+ print("(ERROR \"" + e.toString() + "\")");
+ }
+ catch(Error ex) { }
+ }
+ }
+}
+
diff --git a/org.aspectj.ajdt.core/src/org/aspectj/tools/ajc/Main.java b/org.aspectj.ajdt.core/src/org/aspectj/tools/ajc/Main.java
new file mode 100644
index 000000000..e698d2b40
--- /dev/null
+++ b/org.aspectj.ajdt.core/src/org/aspectj/tools/ajc/Main.java
@@ -0,0 +1,562 @@
+/* *******************************************************************
+ * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC).
+ * All rights reserved.
+ * This program and the accompanying materials are made available
+ * under the terms of the Common Public License v1.0
+ * which accompanies this distribution and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * Xerox/PARC initial implementation
+ * ******************************************************************/
+
+
+
+package org.aspectj.tools.ajc;
+
+import org.aspectj.bridge.AbortException;
+import org.aspectj.bridge.ICommand;
+import org.aspectj.bridge.IMessage;
+import org.aspectj.bridge.IMessageHandler;
+import org.aspectj.bridge.IMessageHolder;
+import org.aspectj.bridge.Message;
+import org.aspectj.bridge.MessageHandler;
+import org.aspectj.bridge.MessageUtil;
+import org.aspectj.bridge.ReflectionFactory;
+import org.aspectj.bridge.Version;
+import org.aspectj.util.LangUtil;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.PrintStream;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * Programmatic and command-line interface to AspectJ compiler.
+ * The compiler is an ICommand obtained by reflection.
+ * Not thread-safe.
+ */
+public class Main {
+
+ /** @param args the String[] of command-line arguments */
+ public static void main(String[] args) throws IOException {
+ new Main().runMain(args, true);
+ }
+
+
+ /** append nothing if numItems is 0,
+ * numItems + label + (numItems > 1? "s" : "") otherwise,
+ * prefixing with " " if sink has content
+ */
+ private static void appendNLabel(StringBuffer sink, String label, int numItems) {
+ if (0 == numItems) {
+ return;
+ }
+ if (0 < sink.length()) {
+ sink.append(", ");
+ }
+ sink.append(numItems + " ");
+ if (!LangUtil.isEmpty(label)) {
+ sink.append(label);
+ }
+ if (1 < numItems) {
+ sink.append("s");
+ }
+ }
+
+ /** control iteration/continuation for command (compiler) */
+ protected CommandController controller;
+
+ /** ReflectionFactory identifier for command (compiler) */
+ protected String commandName;
+
+ /** client-set message sink */
+ private IMessageHolder clientHolder;
+
+ /** internally-set message sink */
+ private final MessageHandler ourHandler;
+
+ private int lastFails;
+ private int lastErrors;
+
+ public Main() {
+ controller = new CommandController();
+ commandName = ReflectionFactory.ECLIPSE;
+ ourHandler = new MessageHandler(true);
+ }
+
+ /**
+ * Run without throwing exceptions but optionally using System.exit(..).
+ * This sets up a message handler which emits messages immediately,
+ * so report(boolean, IMessageHandler) only reports total number
+ * of errors or warnings.
+ * @param args the String[] command line for the compiler
+ * @param useSystemExit if true, use System.exit(int) to complete
+ * unless one of the args is -noExit.
+ * and signal result (0 no exceptions/error, <0 exceptions, >0 compiler errors).
+ */
+ public void runMain(String[] args, boolean useSystemExit) {
+ boolean verbose = (-1 != ("" + LangUtil.arrayAsList(args)).indexOf("-verbose"));
+ IMessageHolder holder = clientHolder;
+ if (null == holder) {
+ holder = ourHandler;
+ if (verbose) {
+ ourHandler.setInterceptor(MessagePrinter.VERBOSE);
+ } else {
+ ourHandler.ignore(IMessage.INFO);
+ ourHandler.setInterceptor(MessagePrinter.TERSE);
+ }
+ }
+ run(args, holder);
+
+ boolean skipExit = false;
+ if (useSystemExit && !LangUtil.isEmpty(args)) { // sigh - pluck -noExit
+ for (int i = 0; i < args.length; i++) {
+ if ("-noExit".equals(args[i])) {
+ skipExit = true;
+ break;
+ }
+ }
+ }
+ if (useSystemExit && !skipExit) {
+ systemExit(holder);
+ }
+ }
+
+ /**
+ * Run without using System.exit(..), putting all messages in holder:
+ * <ul>
+ * <li>ERROR: compiler error</li>
+ * <li>WARNING: compiler warning</li>
+ * <li>FAIL: command error (bad arguments, exception thrown)</li>
+ * </ul>
+ * This handles incremental behavior:
+ * <ul>
+ * <li>If args include "-incremental", repeat for every input char
+ * until 'q' is entered.<li>
+ * <li>If args include "-incrementalTagFile {file}", repeat every time
+ * we detect that {file} modification time has changed. </li>
+ * <li>Either way, list files recompiled each time if args includes "-verbose".</li>
+ * <li>Exit when the commmand/compiler throws any Throwable.</li>
+ * </ul>
+ * When complete, this contains all the messages of the final
+ * run of the command and/or any FAIL messages produced in running
+ * the command, including any Throwable thrown by the command itself.
+ *
+ * @param args the String[] command line for the compiler
+ * @param holder the MessageHandler sink for messages.
+ */
+ public void run(String[] args, IMessageHolder holder) {
+ if (LangUtil.isEmpty(args)) {
+ args = new String[] { "-help" };
+ } else if (Arrays.asList(args).contains("-version")) {
+ System.out.println("AspectJ Compiler " + Version.text);
+ System.out.println();
+ return;
+ } else if (controller.running()) {
+ fail(holder, "already running with controller: " + controller, null);
+ return;
+ }
+ args = controller.init(args, holder);
+ if ((0 < holder.numMessages(IMessage.ERROR, true))
+ || (!validArgs(args, controller.incremental(), holder))) {
+ return;
+ }
+ ICommand command = ReflectionFactory.makeCommand(commandName, holder);
+ if (0 < holder.numMessages(IMessage.ERROR, true)) {
+ return;
+ }
+ try {
+ boolean verbose = (-1 != ("" + Arrays.asList(args)).indexOf("-verbose"));
+ boolean passed = command.runCommand(args, holder);
+ if (report(passed, holder) && controller.incremental()) {
+ final boolean onCommandLine = controller.commandLineIncremental();
+ while (controller.doRepeatCommand()) {
+ passed = command.repeatCommand(holder);
+ if (!report(passed, holder)) {
+ break;
+ } else {
+ holder.clearMessages();
+ }
+ }
+ }
+ } catch (AbortException ae) {
+ if (AbortException.ABORT.equals(ae)) {
+ quit();
+ } else {
+ IMessage message = ae.getIMessage();
+ Throwable thrown = ae.getThrown();
+ if (null == thrown) { // toss AbortException wrapper
+ if (null != message) {
+ holder.handleMessage(message);
+ } else {
+ fail(holder, "abort without message", ae);
+ }
+ } else if (null == message) {
+ fail(holder, "aborted", thrown);
+ } else {
+ String mssg = MessageUtil.MESSAGE_MOST.renderToString(message);
+ fail(holder, mssg, thrown);
+ }
+ }
+ } catch (Throwable t) {
+ fail(holder, "thrown?", t);
+ }
+ }
+
+ /** call this to stop after the next iteration of incremental compile */
+ public void quit() {
+ controller.quit();
+ }
+
+ /**
+ * Set holder to be passed all messages.
+ * When holder is set, messages will not be printed by default.
+ * @param holder the IMessageHolder sink for all messages
+ * (use null to restore default behavior)
+ */
+ public void setHolder(IMessageHolder holder) {
+ clientHolder = holder;
+ }
+
+ /**
+ * Nicer messages for some illegal argument combinations
+ */
+ protected boolean validArgs(
+ String[] args,
+ boolean incremental,
+ IMessageHandler handler) {
+ if (incremental) {
+ List list = LangUtil.arrayAsList(args);
+ if (!list.contains("-sourceroots")) { // XXX -sourceroot name
+ fail(handler, "incremental mode requires -sourceroots", null);
+ return false;
+ }
+ // XXX also check for -argfile, @... or ...[.java|.aj]
+ }
+ return true;
+ }
+
+ /**
+ * Call System.exit(int) with values derived from the number
+ * of failures/aborts or errors in messages.
+ * @param messages the IMessageHolder to interrogate.
+ * @param messages
+ */
+ protected void systemExit(IMessageHolder messages) {
+ int num = lastFails; // messages.numMessages(IMessage.FAIL, true);
+ if (0 < num) {
+ System.exit(-num);
+ }
+ num = lastErrors; // messages.numMessages(IMessage.ERROR, false);
+ if (0 < num) {
+ System.exit(num);
+ }
+ System.exit(0);
+ }
+
+ /** Messages to the user */
+ protected void outMessage(String message) { // XXX coordinate with MessagePrinter
+ System.out.print(message);
+ System.out.flush();
+ }
+
+ /**
+ * Report results from a (possibly-incremental) compile run.
+ * This delegates to any reportHandler or otherwise
+ * prints summary counts of errors/warnings to System.err (if any errors)
+ * or System.out (if only warnings).
+ * WARNING: this silently ignores other messages like FAIL,
+ * but clears the handler of all messages when returning true. XXX false
+ *
+ * This implementation ignores the pass parameter but
+ * clears the holder after reporting
+ * on the assumption messages were handled/printed already.
+ * (ignoring UnsupportedOperationException from holder.clearMessages()).
+ * @param pass true result of the command
+ * @param holder IMessageHolder with messages from the command
+ * @see reportCommandResults(IMessageHolder)
+ * @return false if the process should abort
+ */
+ protected boolean report(boolean pass, IMessageHolder holder) {
+ lastFails = holder.numMessages(IMessage.FAIL, true);
+ boolean result = (0 == lastFails);
+ if (holder == ourHandler) {
+ lastErrors = holder.numMessages(IMessage.ERROR, false);
+ int warnings = holder.numMessages(IMessage.WARNING, false);
+ StringBuffer sb = new StringBuffer();
+ appendNLabel(sb, "fail|abort", lastFails);
+ appendNLabel(sb, "error", lastErrors);
+ appendNLabel(sb, "warning", warnings);
+ if (0 < sb.length()) {
+ PrintStream out = (0 < (lastErrors + lastFails)
+ ? System.err
+ : System.out);
+ out.println(""); // XXX "wrote class file" messages no eol?
+ out.println(sb.toString());
+ if (false) { // printed elsewhere so printed when found
+ if (0 < lastFails) {
+ MessageUtil.print(System.err, holder, "", MessageUtil.MESSAGE_ALL, MessageUtil.PICK_FAIL_PLUS);
+ }
+ if (0 < lastErrors) {
+ MessageUtil.print(System.err, holder, "", MessageUtil.MESSAGE_ALL, MessageUtil.PICK_ERROR);
+ }
+ if (0 < warnings) {
+ MessageUtil.print(System.err, holder, "", MessageUtil.MESSAGE_ALL, MessageUtil.PICK_WARNING);
+ }
+ }
+ }
+ }
+ return result;
+ }
+
+ /** convenience API to make fail messages (without MessageUtils's fail prefix) */
+ protected static void fail(IMessageHandler handler, String message, Throwable thrown) {
+ handler.handleMessage(new Message(message, IMessage.FAIL, thrown, null));
+ }
+
+ /** interceptor IMessageHandler to print as we go */
+ public static class MessagePrinter implements IMessageHandler {
+ // XXX change as needed before each release
+ public static final String THROWN_PREFIX =
+ "Exception thrown from AspectJ "+ Version.text + LangUtil.EOL
+ + ""+ LangUtil.EOL
+ + "Please email to us as follows:" + LangUtil.EOL
+ + " to: jitterbug@aspectj.org" + LangUtil.EOL
+ + " subject: top stack trace File:line, e.g., \"SomeFile.java:243\"" + LangUtil.EOL
+ + " message: copy the entire stack trace." + LangUtil.EOL
+ + "" + LangUtil.EOL
+ + "Your message can also request follow-up or provide a workaround." + LangUtil.EOL
+ + "To make the bug a priority, please include a test program." + LangUtil.EOL
+ + "" + LangUtil.EOL
+ + "You may search for duplicate bugs (i.e., known workarounds):" + LangUtil.EOL
+ + "" + LangUtil.EOL
+ + "http://aspectj.org/bugs" + LangUtil.EOL
+ + "http://aspectj.org/bugs/incoming?expression=SomeFile.java:243" + LangUtil.EOL
+ + "" + LangUtil.EOL;
+
+ public static final IMessageHandler VERBOSE
+ = new MessagePrinter(true);
+ public static final IMessageHandler TERSE
+ = new MessagePrinter(false);
+
+ final boolean verbose;
+ protected MessagePrinter(boolean verbose) {
+ this.verbose = verbose;
+ }
+
+ /**
+ * Print errors and warnings to System.err,
+ * and optionally info to System.out,
+ * rendering message String only.
+ * @return false always
+ */
+ public boolean handleMessage(IMessage message) {
+ if (null != message) {
+ PrintStream out = getStreamFor(message.getKind());
+ if (null != out) {
+ out.println(render(message));
+ }
+ }
+ return false;
+ }
+
+ protected String render(IMessage message) {
+ IMessage.Kind kind = message.getKind();
+ if (kind.equals(IMessage.ABORT)) {
+ Throwable t = message.getThrown();
+ if (null == t) {
+ return "abort (no message)";
+ } else {
+ return render(t);
+ }
+ }
+ String m = message.getMessage();
+ if (LangUtil.isEmpty(m)) {
+ m = message.toString();
+ }
+ return m;
+ }
+
+ protected String render(Throwable t) {
+ String m = t.getMessage();
+ return THROWN_PREFIX
+ + (null != m ? m + "\n": "")
+ + LangUtil.renderException(t, true);
+ }
+
+ public boolean isIgnoring(IMessage.Kind kind) {
+ return (null != getStreamFor(kind));
+ }
+
+ /** @return System.err for FAIL, ABORT, ERROR, and WARNING,
+ * System.out for INFO if verbose.
+ */
+ protected PrintStream getStreamFor(IMessage.Kind kind) {
+ if (IMessage.FAIL.equals(kind)
+ || IMessage.ERROR.equals(kind)
+ || IMessage.WARNING.equals(kind)
+ || IMessage.ABORT.equals(kind)) {
+ return System.err;
+ } else if (verbose && IMessage.INFO.equals(kind)) {
+ return System.out;
+ } else {
+ return null;
+ }
+ }
+ }
+
+ /** controller for repeatable command delays until input or file changed or removed */
+ public static class CommandController {
+ public static String TAG_FILE_OPTION = "-XincrementalFile";
+ public static String INCREMENTAL_OPTION = "-incremental";
+
+ /** maximum 10-minute delay between filesystem checks */
+ public static long MAX_DELAY = 1000 * 600;
+
+ /** default 5-second delay between filesystem checks */
+ public static long DEFAULT_DELAY = 1000 * 5;
+
+ /** @see init(String[]) */
+ private static String[][] OPTIONS = new String[][]
+ { new String[] { INCREMENTAL_OPTION },
+ new String[] { TAG_FILE_OPTION, null } };
+
+
+ /** true between init(String[]) and doRepeatCommand() that returns false */
+ private boolean running;
+
+ /** true after quit() called */
+ private boolean quit;
+
+ /** true if incremental mode, waiting for input other than 'q' */
+ private boolean incremental;
+
+ /** true if incremental mode, waiting for file to change (repeat) or disappear (quit) */
+ private File tagFile;
+
+ /** last modification time for tagFile as of last command - 0 to start */
+ private long fileModTime;
+
+ /** delay between filesystem checks for tagFile modification time */
+ private long delay;
+
+ public CommandController() {
+ delay = DEFAULT_DELAY;
+ }
+
+ /**
+ * @param argList read and strip incremental args from this
+ * @param sink IMessageHandler for error messages
+ * @return String[] remainder of args
+ */
+ public String[] init(String[] args, IMessageHandler sink) {
+ running = true;
+ if (!LangUtil.isEmpty(args)) {
+ String[][] options = LangUtil.copyStrings(OPTIONS);
+ args = LangUtil.extractOptions(args, options);
+ incremental = (null != options[0][0]);
+ if (null != options[1][0]) {
+ tagFile = new File(options[1][1]);
+ if (!tagFile.exists()) {
+ MessageUtil.abort(sink, "tag file does not exist: " + tagFile);
+ }
+ }
+ }
+ return args;
+ }
+
+ /** @return true if init(String[]) called but doRepeatCommand has not
+ * returned false */
+ public boolean running() {
+ return running;
+ }
+
+ /** @param delay milliseconds between filesystem checks */
+ public void setDelay(long delay) {
+ if ((delay > -1) && (delay < MAX_DELAY)) {
+ this.delay = delay;
+ }
+ }
+
+ /** @return true if INCREMENTAL_OPTION or TAG_FILE_OPTION was in args */
+ public boolean incremental() {
+ return (incremental || (null != tagFile));
+ }
+
+
+ /** @return true if INCREMENTAL_OPTION was in args */
+ public boolean commandLineIncremental() {
+ return incremental;
+ }
+
+ public void quit() {
+ if (!quit) {
+ quit = true;
+ }
+ }
+
+ /** @return false if we should quit, true to do another command */
+ boolean doRepeatCommand() {
+ if (!running) {
+ return false;
+ }
+ boolean result = false;
+ if (quit) {
+ result = false;
+ } else if (incremental) {
+ try {
+ System.out.println(" press enter to recompile (q to quit): ");
+ System.out.flush();
+ boolean doMore = false;
+ // seek for one q or a series of [\n\r]...
+ do {
+ int input = System.in.read();
+ if ('q' == input) {
+ break; // result = false;
+ } else if (('\n' == input) || ('\r' == input)) {
+ result = true;
+ } // else eat anything else
+ } while (!result);
+ System.in.skip(Integer.MAX_VALUE);
+ } catch (IOException e) { // XXX silence for error?
+ result = false;
+ }
+ } else if (null != tagFile) {
+ long curModTime;
+ while (true) {
+ if (!tagFile.exists()) {
+ result = false;
+ break;
+ } else if (fileModTime == (curModTime = tagFile.lastModified())) {
+ fileCheckDelay();
+ } else {
+ fileModTime = curModTime;
+ result = true;
+ break;
+ }
+ }
+ } // else, not incremental - false
+ if (!result && running) {
+ running = false;
+ }
+ return result;
+ }
+
+ /** delay between filesystem checks, returning if quit is set */
+ protected void fileCheckDelay() {
+ final Thread thread = Thread.currentThread();
+ long targetTime = System.currentTimeMillis() + delay;
+ long curTime;
+ while (targetTime > (curTime = System.currentTimeMillis())) {
+ if (quit) {
+ return;
+ }
+ try { Thread.sleep(300); } // 1/3-second delta for quit check
+ catch (InterruptedException e) {}
+ }
+ }
+ }
+}
diff --git a/org.aspectj.ajdt.core/src/org/aspectj/workbench/resources/AbstractContainer.java b/org.aspectj.ajdt.core/src/org/aspectj/workbench/resources/AbstractContainer.java
new file mode 100644
index 000000000..edccbfc3f
--- /dev/null
+++ b/org.aspectj.ajdt.core/src/org/aspectj/workbench/resources/AbstractContainer.java
@@ -0,0 +1,64 @@
+/* *******************************************************************
+ * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC).
+ * All rights reserved.
+ * This program and the accompanying materials are made available
+ * under the terms of the Common Public License v1.0
+ * which accompanies this distribution and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * Xerox/PARC initial implementation
+ * ******************************************************************/
+
+
+package org.aspectj.workbench.resources;
+
+import org.eclipse.core.resources.*;
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.runtime.*;
+
+public abstract class AbstractContainer extends AbstractResource implements IContainer {
+
+ public AbstractContainer() {
+ super();
+ }
+
+ public abstract boolean exists(IPath path);
+
+ public IFile[] findDeletedMembersWithHistory(
+ int depth,
+ IProgressMonitor monitor)
+ throws CoreException {
+ throw new RuntimeException("unimplemented");
+ }
+
+ public IResource findMember(IPath path, boolean includePhantoms) {
+ return findMember(path);
+ }
+
+ public abstract IResource findMember(IPath path);
+
+ public IResource findMember(String name, boolean includePhantoms) {
+ return findMember(new Path(name), includePhantoms);
+ }
+
+ public IResource findMember(String name) {
+ return findMember(new Path(name));
+ }
+
+ public abstract IFile getFile(IPath path);
+
+ public abstract IFolder getFolder(IPath path);
+
+ public abstract IResource[] members() throws CoreException;
+
+ public IResource[] members(boolean includePhantoms) throws CoreException {
+ return members();
+ }
+
+ public IResource[] members(int memberFlags) throws CoreException {
+ return members();
+ }
+
+ public final String getFileExtension() { return null; }
+}
diff --git a/org.aspectj.ajdt.core/src/org/aspectj/workbench/resources/AbstractFile.java b/org.aspectj.ajdt.core/src/org/aspectj/workbench/resources/AbstractFile.java
new file mode 100644
index 000000000..249c3b316
--- /dev/null
+++ b/org.aspectj.ajdt.core/src/org/aspectj/workbench/resources/AbstractFile.java
@@ -0,0 +1,121 @@
+/* *******************************************************************
+ * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC).
+ * All rights reserved.
+ * This program and the accompanying materials are made available
+ * under the terms of the Common Public License v1.0
+ * which accompanies this distribution and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * Xerox/PARC initial implementation
+ * ******************************************************************/
+
+
+package org.aspectj.workbench.resources;
+
+import java.io.InputStream;
+
+import org.eclipse.core.resources.*;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.runtime.*;
+
+public abstract class AbstractFile extends AbstractResource implements IFile {
+
+ public AbstractFile() {
+ super();
+ }
+
+ public void appendContents(
+ InputStream source,
+ boolean force,
+ boolean keepHistory,
+ IProgressMonitor monitor)
+ throws CoreException {
+ throw new RuntimeException("unimplemented");
+ }
+
+ public void appendContents(
+ InputStream source,
+ int updateFlags,
+ IProgressMonitor monitor)
+ throws CoreException {
+ appendContents(source, isForce(updateFlags), isHistory(updateFlags), monitor);
+ }
+
+ public abstract void create(
+ InputStream source,
+ boolean force,
+ IProgressMonitor monitor)
+ throws CoreException;
+
+ public void create(
+ InputStream source,
+ int updateFlags,
+ IProgressMonitor monitor)
+ throws CoreException {
+ create(source, isForce(updateFlags), monitor);
+ }
+
+ public void delete(
+ boolean force,
+ boolean keepHistory,
+ IProgressMonitor monitor)
+ throws CoreException {
+ delete(force, monitor);
+ }
+
+ public InputStream getContents() throws CoreException {
+ return getContents(true);
+ }
+
+ public abstract InputStream getContents(boolean force) throws CoreException;
+
+ public abstract int getEncoding() throws CoreException;
+
+ public IFileState[] getHistory(IProgressMonitor monitor)
+ throws CoreException {
+ throw new RuntimeException("unimplemented");
+ }
+
+ public void move(
+ IPath destination,
+ boolean force,
+ boolean keepHistory,
+ IProgressMonitor monitor)
+ throws CoreException {
+ throw new RuntimeException("unimplemented");
+ }
+
+ public void setContents(
+ IFileState source,
+ boolean force,
+ boolean keepHistory,
+ IProgressMonitor monitor)
+ throws CoreException {
+ setContents(source.getContents(), force, keepHistory, monitor);
+ }
+
+ public void setContents(
+ IFileState source,
+ int updateFlags,
+ IProgressMonitor monitor)
+ throws CoreException {
+ setContents(source.getContents(), updateFlags, monitor);
+ }
+
+ public abstract void setContents(
+ InputStream source,
+ boolean force,
+ boolean keepHistory,
+ IProgressMonitor monitor)
+ throws CoreException;
+
+ public void setContents(
+ InputStream source,
+ int updateFlags,
+ IProgressMonitor monitor)
+ throws CoreException {
+ setContents(source, isForce(updateFlags), isHistory(updateFlags), monitor);
+ }
+
+}
diff --git a/org.aspectj.ajdt.core/src/org/aspectj/workbench/resources/AbstractFolder.java b/org.aspectj.ajdt.core/src/org/aspectj/workbench/resources/AbstractFolder.java
new file mode 100644
index 000000000..1e516451e
--- /dev/null
+++ b/org.aspectj.ajdt.core/src/org/aspectj/workbench/resources/AbstractFolder.java
@@ -0,0 +1,62 @@
+/* *******************************************************************
+ * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC).
+ * All rights reserved.
+ * This program and the accompanying materials are made available
+ * under the terms of the Common Public License v1.0
+ * which accompanies this distribution and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * Xerox/PARC initial implementation
+ * ******************************************************************/
+
+
+package org.aspectj.workbench.resources;
+
+import org.eclipse.core.resources.*;
+import org.eclipse.core.resources.IFolder;
+import org.eclipse.core.runtime.*;
+
+public abstract class AbstractFolder extends AbstractContainer implements IFolder {
+
+ public AbstractFolder() {
+ super();
+ }
+
+ public abstract void create(boolean force, boolean local, IProgressMonitor monitor)
+ throws CoreException;
+
+ public void create(
+ int updateFlags,
+ boolean local,
+ IProgressMonitor monitor)
+ throws CoreException {
+ create(isForce(updateFlags), local, monitor);
+ }
+
+ public void delete(
+ boolean force,
+ boolean keepHistory,
+ IProgressMonitor monitor)
+ throws CoreException {
+ delete(force, monitor);
+ }
+
+ public IFile getFile(String name) {
+ return getFile(new Path(name));
+ }
+
+ public IFolder getFolder(String name) {
+ return getFolder(new Path(name));
+ }
+
+ public void move(
+ IPath destination,
+ boolean force,
+ boolean keepHistory,
+ IProgressMonitor monitor)
+ throws CoreException {
+ throw new RuntimeException("unimplemented");
+ }
+
+}
diff --git a/org.aspectj.ajdt.core/src/org/aspectj/workbench/resources/AbstractResource.java b/org.aspectj.ajdt.core/src/org/aspectj/workbench/resources/AbstractResource.java
new file mode 100644
index 000000000..0f2f046ab
--- /dev/null
+++ b/org.aspectj.ajdt.core/src/org/aspectj/workbench/resources/AbstractResource.java
@@ -0,0 +1,248 @@
+/* *******************************************************************
+ * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC).
+ * All rights reserved.
+ * This program and the accompanying materials are made available
+ * under the terms of the Common Public License v1.0
+ * which accompanies this distribution and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * Xerox/PARC initial implementation
+ * ******************************************************************/
+
+
+package org.aspectj.workbench.resources;
+
+import org.eclipse.core.resources.*;
+import org.eclipse.core.runtime.*;
+
+public abstract class AbstractResource implements IResource {
+
+ public AbstractResource() {
+ super();
+ }
+
+ public void accept(IResourceVisitor visitor) throws CoreException {
+ throw new RuntimeException("unimplemented");
+ }
+
+ public void accept(
+ IResourceVisitor visitor,
+ int depth,
+ boolean includePhantoms)
+ throws CoreException {
+ throw new RuntimeException("unimplemented");
+ }
+
+ public void accept(IResourceVisitor visitor, int depth, int memberFlags)
+ throws CoreException {
+ throw new RuntimeException("unimplemented");
+ }
+
+ public void clearHistory(IProgressMonitor monitor) throws CoreException {
+ // nothing to do
+ }
+
+ public void copy(
+ IProjectDescription description,
+ boolean force,
+ IProgressMonitor monitor)
+ throws CoreException {
+ throw new RuntimeException("unimplemented");
+ }
+
+ public abstract void copy(
+ IPath destination,
+ boolean force,
+ IProgressMonitor monitor)
+ throws CoreException;
+
+ public void copy(
+ IProjectDescription description,
+ int updateFlags,
+ IProgressMonitor monitor)
+ throws CoreException {
+ throw new RuntimeException("unimplemented");
+ }
+
+ public void copy(
+ IPath destination,
+ int updateFlags,
+ IProgressMonitor monitor)
+ throws CoreException {
+ copy(destination, isForce(updateFlags), monitor);
+ }
+
+ protected static boolean isForce(int updateFlags) {
+ return (updateFlags & IResource.FORCE) != 0;
+ }
+
+ protected static boolean isHistory(int updateFlags) {
+ return (updateFlags & IResource.KEEP_HISTORY) != 0;
+ }
+
+ public IMarker createMarker(String type) throws CoreException {
+ throw new RuntimeException("unimplemented");
+ }
+
+ public abstract void delete(boolean force, IProgressMonitor monitor)
+ throws CoreException;
+
+ public void delete(int updateFlags, IProgressMonitor monitor)
+ throws CoreException {
+ delete(isForce(updateFlags), monitor);
+ }
+
+ public void deleteMarkers(String type, boolean includeSubtypes, int depth)
+ throws CoreException {
+ throw new RuntimeException("unimplemented");
+ }
+
+ public abstract boolean exists();
+
+ public IMarker findMarker(long id) throws CoreException {
+ throw new RuntimeException("unimplemented");
+ }
+
+ public IMarker[] findMarkers(
+ String type,
+ boolean includeSubtypes,
+ int depth)
+ throws CoreException {
+ throw new RuntimeException("unimplemented");
+ }
+
+ public abstract String getFileExtension();
+
+ public abstract IPath getFullPath();
+
+ public abstract IPath getLocation();
+
+ public IMarker getMarker(long id) {
+ throw new RuntimeException("unimplemented");
+ }
+
+ public abstract long getModificationStamp();
+
+ public abstract String getName();
+
+ public abstract IContainer getParent();
+
+ public String getPersistentProperty(QualifiedName key)
+ throws CoreException {
+ throw new RuntimeException("unimplemented");
+ }
+
+ public IProject getProject() {
+ throw new RuntimeException("unimplemented");
+ }
+
+ public IPath getProjectRelativePath() {
+ throw new RuntimeException("unimplemented");
+ }
+
+ public Object getSessionProperty(QualifiedName key) throws CoreException {
+ throw new RuntimeException("unimplemented");
+ }
+
+ public abstract int getType();
+
+ public IWorkspace getWorkspace() {
+ throw new RuntimeException("unimplemented");
+ }
+
+ public boolean isAccessible() {
+ return exists();
+ }
+
+ public boolean isLocal(int depth) {
+ return true;
+ }
+
+ public boolean isPhantom() {
+ return false;
+ }
+
+ public abstract boolean isReadOnly();
+
+ public boolean isSynchronized(int depth) {
+ return true;
+ }
+
+ public void move(
+ IProjectDescription description,
+ boolean force,
+ boolean keepHistory,
+ IProgressMonitor monitor)
+ throws CoreException {
+ throw new RuntimeException("unimplemented");
+ }
+
+ public void move(
+ IPath destination,
+ boolean force,
+ IProgressMonitor monitor)
+ throws CoreException {
+ throw new RuntimeException("unimplemented"); //??? we could make abstract
+ }
+
+ public void move(
+ IProjectDescription description,
+ int updateFlags,
+ IProgressMonitor monitor)
+ throws CoreException {
+ throw new RuntimeException("unimplemented");
+ }
+
+ public void move(
+ IPath destination,
+ int updateFlags,
+ IProgressMonitor monitor)
+ throws CoreException {
+ move(destination, isForce(updateFlags), monitor);
+ }
+
+ public void refreshLocal(int depth, IProgressMonitor monitor)
+ throws CoreException {
+ throw new RuntimeException("unimplemented");
+ }
+
+ public void setLocal(boolean flag, int depth, IProgressMonitor monitor)
+ throws CoreException {
+ throw new RuntimeException("unimplemented");
+ }
+
+ public void setPersistentProperty(QualifiedName key, String value)
+ throws CoreException {
+ throw new RuntimeException("unimplemented");
+ }
+
+ public abstract void setReadOnly(boolean readOnly);
+
+ public void setSessionProperty(QualifiedName key, Object value)
+ throws CoreException {
+ throw new RuntimeException("unimplemented");
+ }
+
+ public abstract void touch(IProgressMonitor monitor) throws CoreException;
+
+ public abstract boolean isDerived();
+
+ public void setDerived(boolean isDerived) throws CoreException {
+ throw new RuntimeException("unimplemented");
+ }
+
+ public boolean isTeamPrivateMember() {
+ return false;
+ }
+
+ public void setTeamPrivateMember(boolean isTeamPrivate)
+ throws CoreException {
+ throw new RuntimeException("unimplemented");
+ }
+
+ public Object getAdapter(Class adapter) {
+ throw new RuntimeException("unimplemented");
+ }
+
+}
diff --git a/org.aspectj.ajdt.core/src/org/aspectj/workbench/resources/FilesystemFile.java b/org.aspectj.ajdt.core/src/org/aspectj/workbench/resources/FilesystemFile.java
new file mode 100644
index 000000000..5c7dbd0bf
--- /dev/null
+++ b/org.aspectj.ajdt.core/src/org/aspectj/workbench/resources/FilesystemFile.java
@@ -0,0 +1,193 @@
+/* *******************************************************************
+ * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC).
+ * All rights reserved.
+ * This program and the accompanying materials are made available
+ * under the terms of the Common Public License v1.0
+ * which accompanies this distribution and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * Xerox/PARC initial implementation
+ * ******************************************************************/
+
+
+package org.aspectj.workbench.resources;
+
+import java.io.*;
+
+import org.aspectj.util.FileUtil;
+import org.eclipse.core.internal.resources.*;
+import org.eclipse.core.resources.*;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.runtime.*;
+
+public class FilesystemFile extends AbstractFile implements IFile {
+
+ private java.io.File file;
+
+ public FilesystemFile(String pathname) {
+ super();
+ file = new java.io.File(pathname);
+ }
+
+ public FilesystemFile(IPath path) {
+ super();
+ file = path.toFile();
+ }
+
+ /**
+ * Closes the source stream.
+ */
+ public void create(
+ InputStream source,
+ boolean force,
+ IProgressMonitor monitor)
+ throws CoreException {
+ FileOutputStream destination = null;
+ try {
+ try {
+ byte[] buffer = new byte[Math.max(256, source.available())]; //XXX does available always work?
+ //??? is this always right
+ file.getParentFile().mkdirs();
+
+ destination = new FileOutputStream(file);
+
+ while (true) {
+ int bytesRead = -1;
+ bytesRead = source.read(buffer);
+ // System.out.println("READ: " + bytesRead);
+ if (bytesRead == -1)
+ break;
+ if (bytesRead == 0) {
+ throw new RuntimeException("read 0 bytes");
+ }
+ destination.write(buffer, 0, bytesRead);
+ if (monitor != null) monitor.worked(1);
+ }
+ } finally {
+ if (destination != null) destination.close();
+ source.close();
+ }
+ } catch (IOException e) {
+ throw new RuntimeException("unexpected: " + e);
+ //throw new CoreException(new IStatus() {});
+ }
+ }
+
+ public InputStream getContents(boolean force) throws CoreException {
+ try {
+ return new FileInputStream(file);
+ } catch (FileNotFoundException fnfe) {
+ throw new CoreException(null);
+ }
+ }
+
+ public int getEncoding() throws CoreException {
+ return 0;
+ }
+
+ public void setContents(
+ InputStream source,
+ boolean force,
+ boolean keepHistory,
+ IProgressMonitor monitor)
+ throws CoreException {
+ create(source, force, monitor);
+ }
+
+ public void copy(
+ IPath destination,
+ boolean force,
+ IProgressMonitor monitor)
+ throws CoreException {
+ throw new RuntimeException("unimplemented");
+ }
+
+ public java.io.File getFile() {
+ return file;
+ }
+
+ public void delete(boolean force, IProgressMonitor monitor)
+ throws CoreException
+ {
+ if (!file.delete()) {
+ throw new RuntimeException("couldn't delete: " + this); //XXX should be CoreException
+ }
+ }
+
+ public boolean exists() {
+ return file.exists() && file.isFile();
+ }
+
+ public String getFileExtension() {
+ String fileName = file.getName();
+ int dotIndex = fileName.indexOf('.');
+ if (dotIndex != -1) {
+ return fileName.substring(dotIndex+1);
+ } else {
+ return null;
+ }
+ }
+
+ public IPath getFullPath() {
+ return new Path(file.getPath());
+ }
+
+ public IPath getLocation() {
+ return new Path(file.getAbsolutePath());
+ }
+
+ public long getModificationStamp() {
+ return file.lastModified();
+ }
+
+ public String getName() {
+ return file.getName();
+ }
+
+ /**
+ * This will create a new instance of a folder rather than looking up a new
+ * folder first.
+ *
+ * ??? is the above correct
+ */
+ public IContainer getParent() {
+ return new FilesystemFolder(file.getParent());
+ }
+
+ public int getType() {
+ return IResource.FILE;
+ }
+
+ public boolean isDerived() {
+ return false;
+ }
+
+ public boolean isReadOnly() {
+ if (!file.canWrite()) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ public void setReadOnly(boolean readOnly) {
+ if (readOnly) {
+ file.setReadOnly();
+ }
+ }
+
+ public void touch(IProgressMonitor monitor) throws CoreException {
+ throw new RuntimeException("unimplemented");
+ }
+
+ public String toString() {
+ return getFullPath().toString();
+ }
+
+// private IStatus genStatus(Throwable t) {
+// return new Status(IStatus.ERROR, "", 0, "file operation failed for: " + file.getName(), t);
+// }
+
+
+}
diff --git a/org.aspectj.ajdt.core/src/org/aspectj/workbench/resources/FilesystemFolder.java b/org.aspectj.ajdt.core/src/org/aspectj/workbench/resources/FilesystemFolder.java
new file mode 100644
index 000000000..7084f1187
--- /dev/null
+++ b/org.aspectj.ajdt.core/src/org/aspectj/workbench/resources/FilesystemFolder.java
@@ -0,0 +1,134 @@
+/* *******************************************************************
+ * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC).
+ * All rights reserved.
+ * This program and the accompanying materials are made available
+ * under the terms of the Common Public License v1.0
+ * which accompanies this distribution and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * Xerox/PARC initial implementation
+ * ******************************************************************/
+
+
+package org.aspectj.workbench.resources;
+
+import org.apache.bcel.generic.RETURN;
+import org.eclipse.core.resources.*;
+import org.eclipse.core.runtime.*;
+
+/**
+ * When lookup for parent or contained paths is done a new instance of a folder or file
+ * is returned instead of using an existing instance.
+ *
+ * ??? is the above correct behavior
+ */
+public class FilesystemFolder extends AbstractFolder implements IFolder {
+
+ private java.io.File dir;
+
+ public FilesystemFolder(IPath path) {
+ super();
+ dir = path.toFile();
+ }
+
+
+ public FilesystemFolder(String pathname) {
+ super();
+ dir = new java.io.File(pathname);
+ }
+
+ public void create(boolean force, boolean local, IProgressMonitor monitor)
+ throws CoreException
+ {
+ dir.mkdir();
+ }
+
+ public void copy(
+ IPath destination,
+ boolean force,
+ IProgressMonitor monitor)
+ throws CoreException
+ {
+ throw new RuntimeException("unimplemented");
+ }
+
+ public void delete(boolean force, IProgressMonitor monitor)
+ throws CoreException {
+ dir.delete();
+ }
+
+ public boolean exists() {
+ return dir.exists() && dir.isDirectory();
+ }
+
+ public IPath getFullPath() {
+ return new Path(dir.getPath());
+ }
+
+ public IPath getLocation() {
+ return new Path(dir.getAbsolutePath());
+ }
+
+ public long getModificationStamp() {
+ return dir.lastModified();
+ }
+
+ public String getName() {
+ return dir.getName();
+ }
+
+ public int getType() {
+ return IResource.FILE;
+ }
+
+ public boolean isReadOnly() {
+ return !dir.canWrite();
+ }
+
+ public void setReadOnly(boolean readOnly) {
+ if (readOnly) dir.setReadOnly();
+ }
+
+ public void touch(IProgressMonitor monitor) throws CoreException {
+ throw new RuntimeException("unimplemented");
+ }
+
+ public boolean isDerived() {
+ return false;
+ }
+
+ public IContainer getParent() {
+ return new FilesystemFolder(dir.getParent());
+ }
+
+ public boolean exists(IPath path) {
+ String pathString = new java.io.File(path.toString()).getAbsolutePath();
+ String dirPathString = dir.getAbsolutePath();
+ return pathString.startsWith(dirPathString);
+ }
+
+ public IFile getFile(IPath path) {
+ return new FilesystemFile(dir.getPath() + java.io.File.separator + path.toString());
+ }
+
+ public IFolder getFolder(IPath path) {
+ return new FilesystemFolder(dir.getPath() + java.io.File.separator + path.toString());
+ }
+
+ public IResource[] members() throws CoreException {
+ throw new RuntimeException("unimplemented");
+ }
+
+ public IResource findMember(IPath path) {
+ throw new RuntimeException("unimplemented");
+ }
+ /**
+ * @return the full path
+ * ??? is this wrong
+ */
+ public IPath getProjectRelativePath() {
+ return getFullPath();
+ }
+
+}
diff --git a/org.aspectj.ajdt.core/src/org/aspectj/workbench/resources/SimpleProject.java b/org.aspectj.ajdt.core/src/org/aspectj/workbench/resources/SimpleProject.java
new file mode 100644
index 000000000..8cc422798
--- /dev/null
+++ b/org.aspectj.ajdt.core/src/org/aspectj/workbench/resources/SimpleProject.java
@@ -0,0 +1,136 @@
+/* *******************************************************************
+ * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC).
+ * All rights reserved.
+ * This program and the accompanying materials are made available
+ * under the terms of the Common Public License v1.0
+ * which accompanies this distribution and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * Xerox/PARC initial implementation
+ * ******************************************************************/
+
+
+package org.aspectj.workbench.resources;
+
+import java.util.*;
+
+import org.eclipse.core.internal.resources.*;
+import org.eclipse.core.resources.*;
+import org.eclipse.core.runtime.*;
+
+public class SimpleProject extends FilesystemFolder implements IProject {
+ IProjectDescription description;
+
+ public SimpleProject(IPath path, String name) {
+ super(path.toString());
+ description = new ProjectDescription();
+ description.setName(name);
+ description.setLocation(path);
+ }
+
+ public void build(
+ int kind,
+ String builderName,
+ Map args,
+ IProgressMonitor monitor)
+ throws CoreException {
+ throw new RuntimeException("unimplemented");
+ }
+
+ public void build(int kind, IProgressMonitor monitor)
+ throws CoreException {
+ throw new RuntimeException("unimplemented");
+ }
+
+ public void close(IProgressMonitor monitor) throws CoreException {
+ throw new RuntimeException("unimplemented");
+ }
+
+ public void create(
+ IProjectDescription description,
+ IProgressMonitor monitor)
+ throws CoreException {
+ create(monitor);
+ }
+
+ public void create(IProgressMonitor monitor) throws CoreException {
+ throw new RuntimeException("unimplemented");
+ }
+
+ public void delete(
+ boolean deleteContent,
+ boolean force,
+ IProgressMonitor monitor)
+ throws CoreException {
+ throw new RuntimeException("unimplemented");
+ }
+
+ public IProjectDescription getDescription() throws CoreException {
+ return description;
+ }
+
+ public IFile getFile(String name) {
+ throw new RuntimeException("unimplemented");
+ }
+
+ public IFolder getFolder(String name) {
+ throw new RuntimeException("unimplemented");
+ }
+
+ public IProjectNature getNature(String natureId) throws CoreException {
+ throw new RuntimeException("unimplemented");
+ }
+
+ public IPath getPluginWorkingLocation(IPluginDescriptor plugin) {
+ throw new RuntimeException("unimplemented");
+ }
+
+ public IProject[] getReferencedProjects() throws CoreException {
+ throw new RuntimeException("unimplemented");
+ }
+
+ public IProject[] getReferencingProjects() {
+ throw new RuntimeException("unimplemented");
+ }
+
+ public boolean hasNature(String natureId) throws CoreException {
+ return false;
+ }
+
+ public boolean isNatureEnabled(String natureId) throws CoreException {
+ return false;
+ }
+
+ public boolean isOpen() {
+ return false;
+ }
+
+ public void move(
+ IProjectDescription description,
+ boolean force,
+ IProgressMonitor monitor)
+ throws CoreException {
+ throw new RuntimeException("unimplemented");
+ }
+
+ public void open(IProgressMonitor monitor) throws CoreException {
+ throw new RuntimeException("unimplemented");
+ }
+
+ public void setDescription(
+ IProjectDescription description,
+ IProgressMonitor monitor)
+ throws CoreException {
+ throw new RuntimeException("unimplemented");
+ }
+
+ public void setDescription(
+ IProjectDescription description,
+ int updateFlags,
+ IProgressMonitor monitor)
+ throws CoreException {
+ throw new RuntimeException("unimplemented");
+ }
+
+}
diff --git a/org.aspectj.ajdt.core/testdata/Hello.txt b/org.aspectj.ajdt.core/testdata/Hello.txt
new file mode 100644
index 000000000..72c6c3506
--- /dev/null
+++ b/org.aspectj.ajdt.core/testdata/Hello.txt
@@ -0,0 +1,13 @@
+ class Hello extends java.lang.Object:
+ void <init>():
+ ALOAD_0 // Hello this
+ INVOKESPECIAL java.lang.Object.<init> ()V
+ RETURN
+ end void <init>()
+
+ public static void main(String[]):
+ GETSTATIC A.ajc$perSingletonInstance LA;
+ INVOKEVIRTUAL A.ajc_before_1 ()V
+ RETURN
+ end public static void main(String[])
+end class Hello
diff --git a/org.aspectj.ajdt.core/testdata/ajc/A.java b/org.aspectj.ajdt.core/testdata/ajc/A.java
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/org.aspectj.ajdt.core/testdata/ajc/A.java
diff --git a/org.aspectj.ajdt.core/testdata/ajc/B.java b/org.aspectj.ajdt.core/testdata/ajc/B.java
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/org.aspectj.ajdt.core/testdata/ajc/B.java
diff --git a/org.aspectj.ajdt.core/testdata/ajc/X.aj b/org.aspectj.ajdt.core/testdata/ajc/X.aj
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/org.aspectj.ajdt.core/testdata/ajc/X.aj
diff --git a/org.aspectj.ajdt.core/testdata/ajc/Y.aj b/org.aspectj.ajdt.core/testdata/ajc/Y.aj
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/org.aspectj.ajdt.core/testdata/ajc/Y.aj
diff --git a/org.aspectj.ajdt.core/testdata/ajc/pkg/Hello.java b/org.aspectj.ajdt.core/testdata/ajc/pkg/Hello.java
new file mode 100644
index 000000000..69728b337
--- /dev/null
+++ b/org.aspectj.ajdt.core/testdata/ajc/pkg/Hello.java
@@ -0,0 +1,3 @@
+package pkg;
+
+public class Hello {} \ No newline at end of file
diff --git a/org.aspectj.ajdt.core/testdata/lintspec.properties b/org.aspectj.ajdt.core/testdata/lintspec.properties
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/org.aspectj.ajdt.core/testdata/lintspec.properties
diff --git a/org.aspectj.ajdt.core/testdata/resources/empty.txt b/org.aspectj.ajdt.core/testdata/resources/empty.txt
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/org.aspectj.ajdt.core/testdata/resources/empty.txt
diff --git a/org.aspectj.ajdt.core/testdata/resources/file.txt b/org.aspectj.ajdt.core/testdata/resources/file.txt
new file mode 100644
index 000000000..699b1680f
--- /dev/null
+++ b/org.aspectj.ajdt.core/testdata/resources/file.txt
@@ -0,0 +1,2 @@
+abcd
+12345 \ No newline at end of file
diff --git a/org.aspectj.ajdt.core/testdata/resources/javaFile.txt b/org.aspectj.ajdt.core/testdata/resources/javaFile.txt
new file mode 100644
index 000000000..699b1680f
--- /dev/null
+++ b/org.aspectj.ajdt.core/testdata/resources/javaFile.txt
@@ -0,0 +1,2 @@
+abcd
+12345 \ No newline at end of file
diff --git a/org.aspectj.ajdt.core/testdata/src1/.cvsignore b/org.aspectj.ajdt.core/testdata/src1/.cvsignore
new file mode 100644
index 000000000..c06bd3c77
--- /dev/null
+++ b/org.aspectj.ajdt.core/testdata/src1/.cvsignore
@@ -0,0 +1,2 @@
+*~
+*.class
diff --git a/org.aspectj.ajdt.core/testdata/src1/A.java b/org.aspectj.ajdt.core/testdata/src1/A.java
new file mode 100644
index 000000000..9be597f7e
--- /dev/null
+++ b/org.aspectj.ajdt.core/testdata/src1/A.java
@@ -0,0 +1,41 @@
+public aspect A issingleton() {
+ public void m(int x) {
+ System.out.println(x);
+ }
+
+ pointcut foo(String[] args): I.foo(args) && execution(void Hello.*(..));
+
+ ///XXX add a test for this correctly
+ //XXXpublic int Hello.fromA;
+
+ before(): execution(* Hello.*(..)) {
+ System.out.println("enter");
+ }
+
+
+ public void pingHello(Hello h) {
+ int x = 2;
+ System.out.println(x);
+ }
+
+ public static void main(String[] args) {
+ Hello.main(args);
+ }
+}
+
+class Hello {
+ public static void main(String[] args) {
+ }
+}
+
+
+interface I {
+ pointcut foo(String[] i): args(i);
+
+ static aspect InnerA {
+ before(): this(String) {
+ System.out.println("hi");
+ }
+ }
+ //void foo();
+}
diff --git a/org.aspectj.ajdt.core/testdata/src1/A1.java b/org.aspectj.ajdt.core/testdata/src1/A1.java
new file mode 100644
index 000000000..7f82c3631
--- /dev/null
+++ b/org.aspectj.ajdt.core/testdata/src1/A1.java
@@ -0,0 +1,23 @@
+aspect A1 {
+ after() throwing (Throwable t): execution(* Hello.*(..)) {
+ System.out.println("enter");
+ }
+
+ after() throwing: execution(* Hello.*(..)) {
+ System.out.println("enter");
+ }
+
+ after() returning: execution(* Hello.*(..)) {
+ System.out.println("enter");
+ }
+
+ after(): execution(void Hello.*ai*(..)) {
+ }
+}
+
+
+class Hello {
+ public static void main(String[] args) {
+ System.out.println("hello");
+ }
+}
diff --git a/org.aspectj.ajdt.core/testdata/src1/A2.java b/org.aspectj.ajdt.core/testdata/src1/A2.java
new file mode 100644
index 000000000..c8fd65aa7
--- /dev/null
+++ b/org.aspectj.ajdt.core/testdata/src1/A2.java
@@ -0,0 +1,19 @@
+aspect A2 {
+ after(Object thisObject): target(thisObject) && execution(public * Hello.*(..)) {
+ }
+ after(Object thisObject): this(thisObject) && execution(* Hello.*(..)) {
+ System.out.println(thisObject);
+ }
+ after() returning (String s): execution(* Hello.*(..)) {
+ //System.out.println(s);
+ }
+}
+
+class Hello {
+ public static void main(String[] args) {
+ System.out.println("hello");
+ }
+
+ void m() {
+ }
+}
diff --git a/org.aspectj.ajdt.core/testdata/src1/Ap.java b/org.aspectj.ajdt.core/testdata/src1/Ap.java
new file mode 100644
index 000000000..9975367cf
--- /dev/null
+++ b/org.aspectj.ajdt.core/testdata/src1/Ap.java
@@ -0,0 +1,51 @@
+package src1;
+
+aspect Ap {
+ public void m(int x) {
+ System.out.println(x);
+ }
+
+ pointcut foo(String[] args): args(args) && execution(void Hello.*(..));
+
+ //pointcut ref(): foo12();
+
+ before(): execution(* Hello.*(..)) {
+ System.out.println("enter");
+ }
+
+// before(): get(* java.lang.System.out) {
+// System.out.println("exit get");
+// }
+
+ public int Hello.fromA;
+
+ public void pingHello(Hello h) {
+ int x = 2; //XXXh.fromA;
+ System.out.println(x);
+ }
+
+// after(): abc {
+// System.out.println("enter");
+// }
+// after() throwing (Throwable t): abc {
+// System.out.println("enter");
+// }
+
+// public int Hello.m() {
+// System.out.println("m()");
+// return 10;
+// }
+
+// void around(int x): abc {
+// System.out.println("enter");
+// }
+}
+
+class Hello {
+ public static void main(String[] args) {
+ }
+}
+
+interface I {
+ //void foo();
+}
diff --git a/org.aspectj.ajdt.core/testdata/src1/AroundA.java b/org.aspectj.ajdt.core/testdata/src1/AroundA.java
new file mode 100644
index 000000000..8bc7b2f93
--- /dev/null
+++ b/org.aspectj.ajdt.core/testdata/src1/AroundA.java
@@ -0,0 +1,27 @@
+aspect AroundA {
+ pointcut foo(): execution(void main(..));
+
+ int around(int i, boolean b): args(i, b) && foo() {
+ System.out.println("enter");
+ return proceed(10, false);
+ }
+
+
+ void around(Object a): args(a) && foo() {
+ System.out.println("enter");
+ proceed("new: " + a);
+ System.out.println("exit");
+ }
+
+ void around(final String[] a): args(a) && foo() {
+ Runnable r = new Runnable() {
+ public void run() {
+ proceed(a);
+ }
+ };
+ r.run();
+ r.run();
+ }
+}
+
+ \ No newline at end of file
diff --git a/org.aspectj.ajdt.core/testdata/src1/AroundA1.java b/org.aspectj.ajdt.core/testdata/src1/AroundA1.java
new file mode 100644
index 000000000..8230a80e0
--- /dev/null
+++ b/org.aspectj.ajdt.core/testdata/src1/AroundA1.java
@@ -0,0 +1,45 @@
+public class AroundA1 {
+
+ public static void main(String[] args) {
+ System.err.println(new AroundA1().main(3, (short)1, true));
+ }
+
+ public int main(int xx, short s, boolean yy) {
+ System.err.println(xx);
+ System.err.println(s);
+ System.err.println(yy);
+ return 10;
+ }
+}
+
+aspect MyAroundAspect {
+ int field = 10;
+
+ pointcut foo(): call(int main(..));
+
+ Object around(AroundA1 o, int i, boolean b): target(o) && args(i, *, b) && foo() {
+ System.err.println("enter: " + o + " with " + field);
+ Object x = proceed(o, 10, false);
+ System.err.println("got: " + x);
+ return new Integer(42);
+ }
+
+
+// void around(Object a): args(a) && foo() {
+// System.out.println("enter");
+// proceed("new: " + a);
+// System.out.println("exit");
+// }
+//
+// void around(final String[] a): args(a) && foo() {
+// Runnable r = new Runnable() {
+// public void run() {
+// proceed(a);
+// }
+// };
+// r.run();
+// r.run();
+// }
+}
+
+ \ No newline at end of file
diff --git a/org.aspectj.ajdt.core/testdata/src1/BadA.java b/org.aspectj.ajdt.core/testdata/src1/BadA.java
new file mode 100644
index 000000000..2529297e9
--- /dev/null
+++ b/org.aspectj.ajdt.core/testdata/src1/BadA.java
@@ -0,0 +1,35 @@
+aspect BadA {
+ public void m(int x) {
+ System.out.println(x);
+ }
+
+// pointcut foo(): execution(void Hello.*(..));
+ pointcut foo1(): abc);
+ pointcut foo2(): abc ;
+
+
+
+// pointcut bar(): this(Bazoo);
+
+ //pointcut foo2(): abc;
+ //pointcut foo3(): abc;
+
+// before(): abc {
+// System.out.println("enter");
+// }
+// after(): abc {
+// System.out.println("enter");
+// }
+// after() throwing (Throwable t): abc {
+// System.out.println("enter");
+// }
+
+// public int Hello.m() {
+// System.out.println("m()");
+// return 10;
+// }
+
+// void around(int x): abc {
+// System.out.println("enter");
+// }
+}
diff --git a/org.aspectj.ajdt.core/testdata/src1/BadBinding.java b/org.aspectj.ajdt.core/testdata/src1/BadBinding.java
new file mode 100644
index 000000000..33545b414
--- /dev/null
+++ b/org.aspectj.ajdt.core/testdata/src1/BadBinding.java
@@ -0,0 +1,22 @@
+aspect A2 {
+ after(Object thisObject1): target(thisObject) { // ERR unbound
+ }
+ after(Object o1, Object o2): target(o1) || target(o2) { // ERR inconsistent
+ }
+ after(Object o1, Object o2): target(o1) && target(o2) { // NO PROB
+ }
+ after(Object o1): target(o1) && target(o1) { // ERR multiple
+ }
+ after(Object o1): !target(o1) { // ERR can't bind here
+ }
+ void around(Object o1): target(o1) {
+ proceed(2); //ERR can't convert from int to Object
+ }
+ void around(Object o1): target(o1) {
+ proceed(null, 2); //ERR wrong number of args
+ }
+ void around(Object o1): target(o1) {
+ proceed(); //ERR wrong number of args
+ }
+
+}
diff --git a/org.aspectj.ajdt.core/testdata/src1/BadHello.java b/org.aspectj.ajdt.core/testdata/src1/BadHello.java
new file mode 100644
index 000000000..504e82815
--- /dev/null
+++ b/org.aspectj.ajdt.core/testdata/src1/BadHello.java
@@ -0,0 +1,6 @@
+public class BadHello {
+ public static void main(String[] args) {
+ new BadHello().m();
+ }
+ public void m() { return 2; }
+}
diff --git a/org.aspectj.ajdt.core/testdata/src1/DeclareSoft.java b/org.aspectj.ajdt.core/testdata/src1/DeclareSoft.java
new file mode 100644
index 000000000..b42a82453
--- /dev/null
+++ b/org.aspectj.ajdt.core/testdata/src1/DeclareSoft.java
@@ -0,0 +1,26 @@
+import java.io.*;
+import org.aspectj.lang.*;
+
+public class DeclareSoft {
+ public static void main(String[] args) {
+ try {
+ new DeclareSoft().m();
+ } catch (SoftException se) {
+ return;
+ }
+ }
+
+ void m() {
+ InputStream s = new FileInputStream("foobar");
+ s.close();
+ }
+}
+
+
+aspect A {
+ //declare soft: IOException: execution(void m());
+
+ declare soft: IOException: foo();
+
+ pointcut foo(): execution(void m());
+}
diff --git a/org.aspectj.ajdt.core/testdata/src1/DeclareWarning.java b/org.aspectj.ajdt.core/testdata/src1/DeclareWarning.java
new file mode 100644
index 000000000..0c6ecf6b1
--- /dev/null
+++ b/org.aspectj.ajdt.core/testdata/src1/DeclareWarning.java
@@ -0,0 +1,11 @@
+public class DeclareWarning {
+ public void m() { // should be error on this line
+ }
+}
+
+aspect Checker {
+ declare warning: execution(* m()): "too short method name";
+ declare warning: execution(* n()): "too short method name"; // no effect
+}
+
+
diff --git a/org.aspectj.ajdt.core/testdata/src1/Declares.java b/org.aspectj.ajdt.core/testdata/src1/Declares.java
new file mode 100644
index 000000000..b3c6a065b
--- /dev/null
+++ b/org.aspectj.ajdt.core/testdata/src1/Declares.java
@@ -0,0 +1,13 @@
+public class Declares {
+ public void m() { // should be error on this line
+ }
+}
+
+aspect Checker {
+ declare error: execution(* m()): "too short method name";
+ declare error: execution(* n()): "too short method name"; // no effect
+
+ //declare warning: exec: "bar";
+}
+
+
diff --git a/org.aspectj.ajdt.core/testdata/src1/DummyAspect.java b/org.aspectj.ajdt.core/testdata/src1/DummyAspect.java
new file mode 100644
index 000000000..dafef6e64
--- /dev/null
+++ b/org.aspectj.ajdt.core/testdata/src1/DummyAspect.java
@@ -0,0 +1,6 @@
+public abstract aspect DummyAspect {
+ public abstract pointcut traced(Object o);
+
+ before (Object exc): traced(exc) {
+ }
+}
diff --git a/org.aspectj.ajdt.core/testdata/src1/Good.java b/org.aspectj.ajdt.core/testdata/src1/Good.java
new file mode 100644
index 000000000..f21b04c6b
--- /dev/null
+++ b/org.aspectj.ajdt.core/testdata/src1/Good.java
@@ -0,0 +1,61 @@
+
+import java.util.*;
+import java.io.IOException;
+
+public class Good {
+
+ public static String foo;
+ public int publicA = 1;
+ private int privateA = 2;
+ protected int protectedA = 3;
+ int packageA = 4;
+
+ { publicA = 5; }
+
+ static { foo = "hi"; }
+
+ public Good() { }
+
+ public void foo() {
+ int i = 0;
+ i += 1;
+ i += 2;
+
+ int aspect = 2;
+
+ System.out.println(1 + aspect +", " + aspect++);
+ }
+
+ { publicA = 6; }
+
+
+ static aspect x { }
+}
+
+aspect A {
+ public void m() { }
+}
+
+/*
+
+aspect A {
+ int j;
+
+ public void m() { }
+
+ pointcut all(): call(* *(..));
+
+ after all(): { System.out.println(""); }
+
+ before(): call(* *(..)) {
+ System.out.println("");
+ }
+}
+
+interface I { }
+*/
+
+//privileged aspect PrivilegedAspect { }
+
+
+
diff --git a/org.aspectj.ajdt.core/testdata/src1/Handler.java b/org.aspectj.ajdt.core/testdata/src1/Handler.java
new file mode 100644
index 000000000..bcb88d7e6
--- /dev/null
+++ b/org.aspectj.ajdt.core/testdata/src1/Handler.java
@@ -0,0 +1,50 @@
+public class Handler {
+ public static void main(String[] args) {
+ m();
+ }
+
+// public static void m() {
+// while(true) {
+// foo: {try {
+// int x = 2+3;
+// if (x >3) break foo;
+// x = x+10;
+// //return;
+// } catch (Throwable t) {
+// System.err.println(t);
+// }}
+// System.out.println("still in loop");
+// }
+// //System.out.println("outside");
+//
+// }
+
+ public static void m() {
+ try {
+ int x = 0;
+ int y = 3/x;
+ throw new RuntimeException("shouldn't be here");
+ } catch (Throwable t) {
+ return;
+ }
+ }
+
+ public void m1(int x) {
+ boolean b = true;
+ if (b) {
+ m();
+ } else {
+ m();
+ }
+ }
+}
+
+aspect A {
+ before(Throwable t): handler(Throwable) && args(t) {
+ System.out.println("caught " + t + " at " + thisJoinPointStaticPart);
+ }
+
+// before(int i): cflow(execution(void m1(int)) && args(i)) && call(void m()) {
+// System.out.println("i");
+// }
+} \ No newline at end of file
diff --git a/org.aspectj.ajdt.core/testdata/src1/Hello.java b/org.aspectj.ajdt.core/testdata/src1/Hello.java
new file mode 100644
index 000000000..9af032526
--- /dev/null
+++ b/org.aspectj.ajdt.core/testdata/src1/Hello.java
@@ -0,0 +1,5 @@
+public class Hello {
+ public static void main(String[] args) {
+ System.out.println("hello world");
+ }
+}
diff --git a/org.aspectj.ajdt.core/testdata/src1/IfPcd.java b/org.aspectj.ajdt.core/testdata/src1/IfPcd.java
new file mode 100644
index 000000000..4318f3d41
--- /dev/null
+++ b/org.aspectj.ajdt.core/testdata/src1/IfPcd.java
@@ -0,0 +1,37 @@
+public aspect IfPcd {
+ private static int foo = 393;
+
+ before(): execution(void IfPcd.main(..)) && if(foo == 393) {
+ System.err.println("Hiya");
+ foo++;
+ main(null); // saved from an infinite loop by the if
+ }
+
+ before(): execution(void IfPcd.main(..)) && if(thisJoinPoint.getThis() == null) {
+ System.err.println("!has this: "+ thisJoinPoint.getThis());
+ }
+
+ before(): execution(void IfPcd.main(..)) && if(thisJoinPointStaticPart.getKind() == "method-execution") {
+ System.err.println("is method-exec");
+ }
+
+
+ before(Object o): execution(void IfPcd.main(..)) && args(o) && if(o != null) {
+ System.err.println("got: " + o);
+ }
+
+ pointcut fun(Object o): args(o) && if(o != null);
+
+ before(Object o1, Object o2): execution(void IfPcd.main(..)) && args(o1) && fun(o2) {
+ System.err.println("got: " + o2);
+ }
+
+ before(): execution(void IfPcd.main(..)) && fun(Object) {
+ System.err.println("got nothin");
+ }
+
+ public static void main(String[] args) {
+ System.err.println("actual body: " + args);
+ }
+}
+
diff --git a/org.aspectj.ajdt.core/testdata/src1/Initialization.java b/org.aspectj.ajdt.core/testdata/src1/Initialization.java
new file mode 100644
index 000000000..4b738a975
--- /dev/null
+++ b/org.aspectj.ajdt.core/testdata/src1/Initialization.java
@@ -0,0 +1,46 @@
+public class Initialization extends Super {
+ public static void main(String[] args) {
+ new Initialization();
+ new Initialization(331);
+ }
+
+ Initialization() {
+ this(98);
+ }
+ Initialization(int i) {
+ super(i+1);
+ foo(i);
+ }
+
+ static void foo(int i) {
+ System.out.println("running foo with " + i);
+ }
+}
+
+class Super {
+ Super(int i) {
+ }
+}
+
+aspect Foo {
+
+
+// void around(int i): initialization(Initialization.new(int)) && args(i) {
+// System.out.println(thisJoinPoint);
+// System.out.println(java.util.Arrays.asList(thisJoinPoint.getArgs()));
+// proceed(993);
+// }
+//
+
+
+ Object around(): preinitialization(Initialization.new()) {
+ System.out.println("i");
+ return null;
+ }
+
+// before(int i): execution(Initialization.new(int)) && args(i) {
+// System.err.println(i);
+// }
+}
+
+
diff --git a/org.aspectj.ajdt.core/testdata/src1/InterType.java b/org.aspectj.ajdt.core/testdata/src1/InterType.java
new file mode 100644
index 000000000..af51afb11
--- /dev/null
+++ b/org.aspectj.ajdt.core/testdata/src1/InterType.java
@@ -0,0 +1,86 @@
+import junit.framework.Assert;
+
+public class InterType {
+
+ public static void main(String[] args) {
+ Target t = new Target();
+ Assert.assertEquals(0, t.i);
+ t.i = 37;
+ Assert.assertEquals(37, t.i);
+ Assert.assertEquals(37, t.i++);
+ Assert.assertEquals(38, t.i);
+ Assert.assertEquals(39, ++t.i);
+ Assert.assertEquals(39, t.i);
+
+ System.out.println("t.i = " + t.i);
+
+ Assert.assertEquals(0, ((I)t).i);
+
+ Assert.assertEquals("foo", t.s);
+ t.s += "-bar";
+ Assert.assertEquals("foo-bar", t.s);
+ System.out.println("t.s = " + t.s);
+
+ // this captures an interesting property of initializers:
+ // that introduced inits run before non-introduced inits
+ Assert.assertEquals("inst00onA", A.getInstS(t));
+ System.out.println("t.instS = " + A.getInstS(t));
+
+ I i = t;
+ Assert.assertEquals("dummy", i.myString);
+ i.myString = "foo";
+ Assert.assertEquals(i.myString, "foo");
+ System.out.println("t.myString = " + t.myString);
+
+ Assert.assertNotNull(A.aspectOf());
+ Assert.assertEquals(A.aspectOf(), A.aspectOf());
+ Assert.assertTrue(A.hasAspect());
+
+ //XXX don't handle constants
+// int x = 10;
+// switch(x) {
+// case Target.CONST: break;
+// default: Assert.fail("bad switch");
+// }
+
+ }
+}
+
+class Target implements I {
+ public int j = 2;
+ private boolean instS = true; // potential conflict need to handle gracefully
+ public boolean getInstS() { return instS; }
+
+ String conflict = "boo";
+}
+
+class SubTarget extends Target {
+ public static String foo() {
+ return A.aspectOf().toString();
+ }
+}
+
+
+interface I { }
+
+
+
+aspect A {
+ private static String aStatic = "onA";
+
+ public int Target.foobarvas = 0;
+ public int I.i = 0;
+ public int Target.i;
+ public static String Target.s = "foo";
+ public static int Target.CONST = 10;
+
+ private String Target.instS = "inst" + j + this.j + aStatic;
+
+ //private String Target.conflict = "goo"; error
+
+ public static String getInstS(Target t) {
+ return t.instS;
+ }
+
+ public String I.myString = "dummy";
+}
diff --git a/org.aspectj.ajdt.core/testdata/src1/InterTypeConstructors.java b/org.aspectj.ajdt.core/testdata/src1/InterTypeConstructors.java
new file mode 100644
index 000000000..d11f3bf4d
--- /dev/null
+++ b/org.aspectj.ajdt.core/testdata/src1/InterTypeConstructors.java
@@ -0,0 +1,73 @@
+import junit.framework.Assert;
+
+public class InterTypeConstructors {
+
+ public static void main(String[] args) {
+ Target t = A.makeT();
+ }
+}
+
+class Target implements I {
+ private Target(String s) {
+ System.err.println(s);
+ }
+
+ public Target() {
+ this(10);
+ }
+
+ int f = 10;
+ static int ss() { return 100; }
+
+ String getS() { return "Target" + this.instS("Foo"); }
+
+ private int instS(String s) { return 10; }
+
+ public int mmmm() { System.err.println("noarg"); return 3;}
+
+}
+
+class C {
+ class SubTarget extends Target {
+ final String s;
+
+ public SubTarget() {
+ super(10);
+ s = "hi";
+ }
+ }
+}
+
+//class SubTarget extends Target {
+// String getS() { return "SubTarget"; }
+// static int ss() { return 10; }
+//
+// public void foobar() {
+// mmmm(333);
+// }
+//
+// //public int mmmm(int x) { return x; }
+//}
+
+interface SuperI {}
+
+
+interface I extends SuperI { }
+
+
+
+aspect A {
+ public static Target makeT() {
+ return new Target(10);
+ }
+
+ Target.new(int foo) {
+ this("hi" + ++foo);
+ this.f = mmmm() + foo;
+ System.err.println(f == 14);
+ }
+
+ //C.SubTarget.new(String value) { // uncomment for an error
+ //this.s = value;
+ //}
+}
diff --git a/org.aspectj.ajdt.core/testdata/src1/InterTypeMethods.java b/org.aspectj.ajdt.core/testdata/src1/InterTypeMethods.java
new file mode 100644
index 000000000..4bc44186c
--- /dev/null
+++ b/org.aspectj.ajdt.core/testdata/src1/InterTypeMethods.java
@@ -0,0 +1,79 @@
+import junit.framework.Assert;
+
+public class InterTypeMethods {
+
+ public static void main(String[] args) {
+ Target t = new Target();
+ Assert.assertEquals(23, t.instM(1));
+ Assert.assertEquals("foo10", A.instS(t, "foo"));
+
+ System.out.println("t: " + t);
+
+ Assert.assertEquals(12, SubTarget.staticM());
+
+ SubTarget st = new SubTarget();
+
+ Assert.assertEquals("100Target10", st.foo());
+
+ st.foobar();
+ t.mmmm(2);
+
+ Assert.assertEquals("xyz-foo", st.onI("xyz-"));
+ }
+}
+
+class Target implements I {
+ int f = 10;
+ static int ss() { return 100; }
+
+ String getS() { return "Target" + this.instS("Foo"); }
+
+ private int instS(String s) { return 10; }
+
+ public int mmmm() { System.err.println("noarg"); return 3;}
+
+}
+
+class SubTarget extends Target {
+ String getS() { return "SubTarget"; }
+ static int ss() { return 10; }
+
+ public void foobar() {
+ mmmm(333);
+ }
+
+ //public int mmmm(int x) { return x; }
+}
+
+interface SuperI {}
+
+
+interface I extends SuperI { }
+
+
+
+aspect A {
+ public static String instS(Target t, String s) {
+ return t.instS(s);
+ }
+
+ public int Target.instM(int x) { return x+2 + f + this.f; }
+ private String Target.instS(String s) { return s + this.f; }
+
+ static int SubTarget.staticM() { return ss() + 2; }
+
+ public String SubTarget.foo() { return super.ss() + super.getS(); }
+
+ public int Target.mmmm(int i) { System.err.println("onearg"); return 3;}
+ public int SubTarget.mmmm(int i) { System.err.println("onearg on Sub"); return 4;}
+
+ public String I.v = "foo";
+
+ public String I.onI(String a) {
+ return a + v;
+ }
+
+ public String SuperI.onI(String a) {
+ return a + "Super";
+ }
+}
diff --git a/org.aspectj.ajdt.core/testdata/src1/MyTrace.java b/org.aspectj.ajdt.core/testdata/src1/MyTrace.java
new file mode 100644
index 000000000..a4b556436
--- /dev/null
+++ b/org.aspectj.ajdt.core/testdata/src1/MyTrace.java
@@ -0,0 +1,7 @@
+aspect MyTrace extends Trace {
+ public pointcut traced(Object foo): this(foo) && execution(* doit(..));
+
+ after(Object o) returning (Object ret): traced(o) {
+ System.out.println("exit: " /*+ thisJoinPoint.getSignature()*/ + " with " + ret);
+ }
+} \ No newline at end of file
diff --git a/org.aspectj.ajdt.core/testdata/src1/Parents.java b/org.aspectj.ajdt.core/testdata/src1/Parents.java
new file mode 100644
index 000000000..17f071927
--- /dev/null
+++ b/org.aspectj.ajdt.core/testdata/src1/Parents.java
@@ -0,0 +1,40 @@
+public class Parents {
+ public static void main(String[] args) {
+ A.I i = new C1();
+ i.m();
+
+ C2 c2 = new C2();
+ c2.m1();
+
+ A.C3 c3 = (A.C3)c2;
+
+ C4 c4 = new C4();
+ c4.m4();
+ }
+}
+
+class C1 {
+ public void m() { System.out.println("m"); }
+}
+
+class C2 {}
+
+class C4 {}
+
+aspect A {
+ static class C3 {
+ public void m1() { System.out.println("from C3"); }
+ }
+
+ interface I {
+ void m();
+ }
+
+ declare parents: (C1 && !C2) implements I;
+ declare parents: C2 extends C3;
+
+ interface I4 {}
+ public void I4.m4() { System.out.println("I.m4"); }
+
+ declare parents: C4 implements I4;
+} \ No newline at end of file
diff --git a/org.aspectj.ajdt.core/testdata/src1/ParentsFail.java b/org.aspectj.ajdt.core/testdata/src1/ParentsFail.java
new file mode 100644
index 000000000..745fb67c9
--- /dev/null
+++ b/org.aspectj.ajdt.core/testdata/src1/ParentsFail.java
@@ -0,0 +1,22 @@
+public class ParentsFail {
+ public static void main(String[] args) {
+ I i = new C1(); // CE incompatible
+ i.m();
+ }
+}
+
+class C1 {
+ public void m() { System.out.println("m"); }
+}
+class C2 {}
+class C3 extends C2 {}
+interface I {
+ void m();
+}
+
+aspect A {
+ declare parents: C2 implements I; // CE can't implement
+ declare parents: C2 extends C3; // CE circular
+
+ declare parents: C1 extends C1; // CE self
+} \ No newline at end of file
diff --git a/org.aspectj.ajdt.core/testdata/src1/PerCflow.java b/org.aspectj.ajdt.core/testdata/src1/PerCflow.java
new file mode 100644
index 000000000..9606c1f75
--- /dev/null
+++ b/org.aspectj.ajdt.core/testdata/src1/PerCflow.java
@@ -0,0 +1,22 @@
+public class PerCflow {
+ public static void main(String[] args) {
+ m();
+ }
+
+ static void m() {
+ System.out.println("m()");
+ }
+}
+
+
+aspect A percflow(pc()) {
+ pointcut pc(): execution(void main(..));
+ static Object o = new Integer(2);
+ before(): execution(void m()) {
+ System.out.println("in " + o.toString());
+ }
+
+ static {
+ o = "hello";
+ }
+} \ No newline at end of file
diff --git a/org.aspectj.ajdt.core/testdata/src1/PerObject.java b/org.aspectj.ajdt.core/testdata/src1/PerObject.java
new file mode 100644
index 000000000..9452ed28a
--- /dev/null
+++ b/org.aspectj.ajdt.core/testdata/src1/PerObject.java
@@ -0,0 +1,22 @@
+public class PerObject {
+ public static void main(String[] args) {
+ new PerObject().m();
+ }
+
+ void m() {
+ System.out.println("m()");
+ }
+}
+
+
+aspect A perthis(pc()) {
+ pointcut pc(): this(PerObject) && execution(* m(..));
+ static Object o = new Integer(2);
+ before(): get(* *) {
+ System.out.println("in " + o.toString());
+ }
+
+ static {
+ o = "hello";
+ }
+} \ No newline at end of file
diff --git a/org.aspectj.ajdt.core/testdata/src1/Privileged.java b/org.aspectj.ajdt.core/testdata/src1/Privileged.java
new file mode 100644
index 000000000..064f1c755
--- /dev/null
+++ b/org.aspectj.ajdt.core/testdata/src1/Privileged.java
@@ -0,0 +1,32 @@
+import java.io.*;
+import org.aspectj.lang.*;
+
+public class Privileged {
+ public static void main(String[] args) {
+ Privileged p = new Privileged();
+
+ System.out.println("got: " + A.getX(p));
+ System.out.println("s: " + s);
+ }
+
+ private int m() {
+ return 2;
+ }
+
+ private int x = 1;
+
+ private static String s = "hi";
+}
+
+
+privileged aspect A {
+ static int getX(Privileged p) {
+ Runnable r = new Runnable() {
+ public void run() {
+ Privileged.s += 10;
+ }
+ };
+ r.run();
+ return p.x + p.m();
+ }
+}
diff --git a/org.aspectj.ajdt.core/testdata/src1/ThisAndModifiers.java b/org.aspectj.ajdt.core/testdata/src1/ThisAndModifiers.java
new file mode 100644
index 000000000..c8fd65aa7
--- /dev/null
+++ b/org.aspectj.ajdt.core/testdata/src1/ThisAndModifiers.java
@@ -0,0 +1,19 @@
+aspect A2 {
+ after(Object thisObject): target(thisObject) && execution(public * Hello.*(..)) {
+ }
+ after(Object thisObject): this(thisObject) && execution(* Hello.*(..)) {
+ System.out.println(thisObject);
+ }
+ after() returning (String s): execution(* Hello.*(..)) {
+ //System.out.println(s);
+ }
+}
+
+class Hello {
+ public static void main(String[] args) {
+ System.out.println("hello");
+ }
+
+ void m() {
+ }
+}
diff --git a/org.aspectj.ajdt.core/testdata/src1/Trace.java b/org.aspectj.ajdt.core/testdata/src1/Trace.java
new file mode 100644
index 000000000..d6aaf17f8
--- /dev/null
+++ b/org.aspectj.ajdt.core/testdata/src1/Trace.java
@@ -0,0 +1,22 @@
+public abstract aspect Trace {
+ public abstract pointcut traced(Object o);
+
+ before (Object exc): traced(exc) {
+ System.out.println("enter: " /*+ thisJoinPoint.getSignature()*/);
+ }
+
+ Object around(): execution(* doit(..)) {
+ Object exc = "Hi";
+ System.out.println("start around: " + exc);
+ Object ret = proceed();
+ System.out.println("exiting around with: " + ret);
+ return ret;
+ }
+
+ Object around(Object exc): traced(exc) {
+ System.out.println("start around(2): " + exc);
+ Object ret = proceed(exc);
+ System.out.println("exiting around with(2): " + ret);
+ return ret;
+ }
+}
diff --git a/org.aspectj.ajdt.core/testdata/src1/TraceHello.java b/org.aspectj.ajdt.core/testdata/src1/TraceHello.java
new file mode 100644
index 000000000..545c58ccc
--- /dev/null
+++ b/org.aspectj.ajdt.core/testdata/src1/TraceHello.java
@@ -0,0 +1,5 @@
+public aspect TraceHello {
+ before(): execution(* Hello.*(..)) {
+ System.out.println("entering: " + thisJoinPoint);
+ }
+} \ No newline at end of file
diff --git a/org.aspectj.ajdt.core/testdata/src1/UnimplementedSyntax.java b/org.aspectj.ajdt.core/testdata/src1/UnimplementedSyntax.java
new file mode 100644
index 000000000..3ea1a1685
--- /dev/null
+++ b/org.aspectj.ajdt.core/testdata/src1/UnimplementedSyntax.java
@@ -0,0 +1,23 @@
+/**
+ *
+ *
+ */
+aspect A dominates Foo persingleton() { }
+
+//aspect B perthis(foo()) {
+//XXX don't forget an error test for foo() not found}
+
+aspect C {
+ pointcut w(int x): args(x) && if(x < 10);
+ pointcut x(): cflow(y());
+ pointcut y(): withincode(int m());
+
+ pointcut z(): execution(void m()) a b c;
+ declare error: execution(void m()): "hi" ac;
+
+ pointcut p(): handler(Foo);
+
+ pointcut p2(): initialization(Object.new(..));
+}
+
+aspect D a b c {} \ No newline at end of file
diff --git a/org.aspectj.ajdt.core/testdata/src1/Xlint.java b/org.aspectj.ajdt.core/testdata/src1/Xlint.java
new file mode 100644
index 000000000..bec51c6d3
--- /dev/null
+++ b/org.aspectj.ajdt.core/testdata/src1/Xlint.java
@@ -0,0 +1,3 @@
+public aspect Xlint {
+ pointcut foo(): this(NotFoundType);
+} \ No newline at end of file
diff --git a/org.aspectj.ajdt.core/testdata/src1/p1/.cvsignore b/org.aspectj.ajdt.core/testdata/src1/p1/.cvsignore
new file mode 100644
index 000000000..6b468b62a
--- /dev/null
+++ b/org.aspectj.ajdt.core/testdata/src1/p1/.cvsignore
@@ -0,0 +1 @@
+*.class
diff --git a/org.aspectj.ajdt.core/testdata/src1/p1/A.java b/org.aspectj.ajdt.core/testdata/src1/p1/A.java
new file mode 100644
index 000000000..be6b96b2f
--- /dev/null
+++ b/org.aspectj.ajdt.core/testdata/src1/p1/A.java
@@ -0,0 +1,28 @@
+aspect A {
+ public void m(int x) {
+ System.out.println(x);
+ }
+
+ pointcut foo(String[] args): args(args) && execution(void Hello.*(..));
+
+ before(): execution(* Hello.*(..)) {
+ System.out.println("enter");
+ }
+
+ public int Hello.fromA;
+
+ public void pingHello(Hello h) {
+ int x = 2;
+ System.out.println(x);
+ }
+
+}
+
+class Hello {
+ public static void main(String[] args) {
+ }
+}
+
+interface I {
+ //void foo();
+}
diff --git a/org.aspectj.ajdt.core/testdata/src1/p1/Foo.java b/org.aspectj.ajdt.core/testdata/src1/p1/Foo.java
new file mode 100644
index 000000000..0a0b8b22a
--- /dev/null
+++ b/org.aspectj.ajdt.core/testdata/src1/p1/Foo.java
@@ -0,0 +1,7 @@
+package p1;
+
+public class Foo {
+ public static void main(String[] args) {
+ System.out.println("Foo");
+ }
+}
diff --git a/org.aspectj.ajdt.core/testdata/src1/trace/ExecTrace.java b/org.aspectj.ajdt.core/testdata/src1/trace/ExecTrace.java
new file mode 100644
index 000000000..c0ac25f34
--- /dev/null
+++ b/org.aspectj.ajdt.core/testdata/src1/trace/ExecTrace.java
@@ -0,0 +1,7 @@
+package trace;
+
+public aspect ExecTrace extends MegaTrace {
+ pointcut where(): execution(public * *(..));
+
+ declare parents: * implements Marker;
+} \ No newline at end of file
diff --git a/org.aspectj.ajdt.core/testdata/src1/trace/MegaTrace.java b/org.aspectj.ajdt.core/testdata/src1/trace/MegaTrace.java
new file mode 100644
index 000000000..dff9a8f20
--- /dev/null
+++ b/org.aspectj.ajdt.core/testdata/src1/trace/MegaTrace.java
@@ -0,0 +1,33 @@
+package trace;
+
+public abstract aspect MegaTrace {
+ abstract pointcut where();
+
+ Object around(): where() {
+ System.out.println("around enter: " + thisJoinPointStaticPart);
+ Object ret = proceed();
+ System.out.println("around exit: " + thisJoinPointStaticPart);
+ return ret;
+ }
+
+ before(): where() {
+ System.out.println("enter: " + thisJoinPointStaticPart);
+ }
+
+ after(): where() {
+ System.out.println("exit: " + thisJoinPointStaticPart);
+ }
+
+
+ declare warning: where() && execution(void main(..)):
+ "tracing execution of main";
+
+ public interface Marker{}
+ private String Marker.name = "foo-bar";
+
+ public String sayHi() { return "hi"; }
+
+ public static String getName(Marker m) {
+ return m.name;
+ }
+} \ No newline at end of file
diff --git a/org.aspectj.ajdt.core/testdata/src1/tracep1/TraceTest.java b/org.aspectj.ajdt.core/testdata/src1/tracep1/TraceTest.java
new file mode 100644
index 000000000..e639bd5a3
--- /dev/null
+++ b/org.aspectj.ajdt.core/testdata/src1/tracep1/TraceTest.java
@@ -0,0 +1,11 @@
+package tracep1;
+
+public class TraceTest {
+
+ public static void test() {
+ TraceTest t = new TraceTest();
+
+ System.out.println(trace.MegaTrace.getName(t));
+ System.out.println(t.sayHi());
+ }
+} \ No newline at end of file
diff --git a/org.aspectj.ajdt.core/testdata/testclasses.jar b/org.aspectj.ajdt.core/testdata/testclasses.jar
new file mode 100644
index 000000000..94cebaa30
--- /dev/null
+++ b/org.aspectj.ajdt.core/testdata/testclasses.jar
Binary files differ
diff --git a/org.aspectj.ajdt.core/testdata/testclasses/Hello.java b/org.aspectj.ajdt.core/testdata/testclasses/Hello.java
new file mode 100644
index 000000000..9af032526
--- /dev/null
+++ b/org.aspectj.ajdt.core/testdata/testclasses/Hello.java
@@ -0,0 +1,5 @@
+public class Hello {
+ public static void main(String[] args) {
+ System.out.println("hello world");
+ }
+}
diff --git a/org.aspectj.ajdt.core/testdata/testclasses/p1/Foo.class b/org.aspectj.ajdt.core/testdata/testclasses/p1/Foo.class
new file mode 100644
index 000000000..d6c418c88
--- /dev/null
+++ b/org.aspectj.ajdt.core/testdata/testclasses/p1/Foo.class
Binary files differ
diff --git a/org.aspectj.ajdt.core/testdata/testclasses/p1/Foo.java b/org.aspectj.ajdt.core/testdata/testclasses/p1/Foo.java
new file mode 100644
index 000000000..0a0b8b22a
--- /dev/null
+++ b/org.aspectj.ajdt.core/testdata/testclasses/p1/Foo.java
@@ -0,0 +1,7 @@
+package p1;
+
+public class Foo {
+ public static void main(String[] args) {
+ System.out.println("Foo");
+ }
+}
diff --git a/org.aspectj.ajdt.core/testsrc/AroundAMain.java b/org.aspectj.ajdt.core/testsrc/AroundAMain.java
new file mode 100644
index 000000000..21cf5e3ec
--- /dev/null
+++ b/org.aspectj.ajdt.core/testsrc/AroundAMain.java
@@ -0,0 +1,47 @@
+/* *******************************************************************
+ * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC).
+ * All rights reserved.
+ * This program and the accompanying materials are made available
+ * under the terms of the Common Public License v1.0
+ * which accompanies this distribution and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * Xerox/PARC initial implementation
+ * ******************************************************************/
+
+import java.util.Arrays;
+
+import junit.framework.TestCase;
+
+import org.aspectj.runtime.internal.AroundClosure;
+import org.aspectj.util.Reflection;
+
+public class AroundAMain extends TestCase {
+
+ public AroundAMain(String name) {
+ super(name);
+ }
+
+
+ public static void main(String[] args) throws ClassNotFoundException {
+ AroundClosure closure = new AroundClosure() {
+ public Object run(Object[] args) throws Throwable {
+// System.out.println("run with: " + Arrays.asList(args));
+ return new Integer(10);
+ }
+ };
+
+ Object instance = Reflection.getStaticField(Class.forName("AroundA"),
+ "ajc$perSingletonInstance");
+
+ Reflection.invoke(Class.forName("AroundA"), instance, "ajc$around$AroundA$46",
+ new Integer(10), new Boolean(true), closure);
+
+ Reflection.invoke(Class.forName("AroundA"), instance, "ajc$around$AroundA$c5",
+ "hello there", closure);
+ Reflection.invoke(Class.forName("AroundA"), instance, "ajc$around$AroundA$150",
+ new String[1], closure);
+
+ }
+}
diff --git a/org.aspectj.ajdt.core/testsrc/EajcModuleTests.java b/org.aspectj.ajdt.core/testsrc/EajcModuleTests.java
new file mode 100644
index 000000000..09bd583ee
--- /dev/null
+++ b/org.aspectj.ajdt.core/testsrc/EajcModuleTests.java
@@ -0,0 +1,33 @@
+/* *******************************************************************
+ * Copyright (c) 1999-2001 Xerox Corporation,
+ * 2002 Palo Alto Research Center, Incorporated (PARC).
+ * All rights reserved.
+ * This program and the accompanying materials are made available
+ * under the terms of the Common Public License v1.0
+ * which accompanies this distribution and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * Xerox/PARC initial implementation
+ * ******************************************************************/
+
+
+// default package
+
+import junit.framework.*;
+import junit.framework.Test;
+
+public class EajcModuleTests extends TestCase {
+
+ public static Test suite() {
+ TestSuite suite = new TestSuite(EajcModuleTests.class.getName());
+ suite.addTest(org.aspectj.ajdt.ajc.AjdtAjcTests.suite());
+ suite.addTest(org.aspectj.ajdt.internal.compiler.batch.AjdtBatchTests.suite());
+ suite.addTest(org.aspectj.ajdt.internal.core.builder.AjdtBuilderTests.suite());
+ suite.addTest(org.aspectj.workbench.resources.WorkspaceResourcesTests.suite());
+ return suite;
+ }
+
+ public EajcModuleTests(String name) { super(name); }
+
+}
diff --git a/org.aspectj.ajdt.core/testsrc/org/aspectj/ajdt/ajc/AjdtAjcTests.java b/org.aspectj.ajdt.core/testsrc/org/aspectj/ajdt/ajc/AjdtAjcTests.java
new file mode 100644
index 000000000..9893c4bcc
--- /dev/null
+++ b/org.aspectj.ajdt.core/testsrc/org/aspectj/ajdt/ajc/AjdtAjcTests.java
@@ -0,0 +1,33 @@
+/* *******************************************************************
+ * Copyright (c) 1999-2001 Xerox Corporation,
+ * 2002 Palo Alto Research Center, Incorporated (PARC).
+ * All rights reserved.
+ * This program and the accompanying materials are made available
+ * under the terms of the Common Public License v1.0
+ * which accompanies this distribution and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * Xerox/PARC initial implementation
+ * ******************************************************************/
+
+
+package org.aspectj.ajdt.ajc;
+
+import junit.framework.*;
+
+public class AjdtAjcTests extends TestCase {
+
+ public static Test suite() {
+ TestSuite suite = new TestSuite(AjdtAjcTests.class.getName());
+ //$JUnit-BEGIN$
+ suite.addTestSuite(AjdtCommandTestCase.class);
+ suite.addTestSuite(BuildArgParserTestCase.class);
+ suite.addTestSuite(ConsoleMessageHandlerTestCase.class);
+ //$JUnit-END$
+ return suite;
+ }
+
+ public AjdtAjcTests(String name) { super(name); }
+
+}
diff --git a/org.aspectj.ajdt.core/testsrc/org/aspectj/ajdt/ajc/AjdtCommandTestCase.java b/org.aspectj.ajdt.core/testsrc/org/aspectj/ajdt/ajc/AjdtCommandTestCase.java
new file mode 100644
index 000000000..40f7f13b4
--- /dev/null
+++ b/org.aspectj.ajdt.core/testsrc/org/aspectj/ajdt/ajc/AjdtCommandTestCase.java
@@ -0,0 +1,111 @@
+/* *******************************************************************
+ * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC).
+ * All rights reserved.
+ * This program and the accompanying materials are made available
+ * under the terms of the Common Public License v1.0
+ * which accompanies this distribution and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * Xerox/PARC initial implementation
+ * ******************************************************************/
+
+
+package org.aspectj.ajdt.ajc;
+
+import org.aspectj.ajdt.internal.core.builder.AjBuildConfig;
+import org.aspectj.bridge.AbortException;
+import org.aspectj.bridge.MessageWriter;
+import org.aspectj.util.StreamPrintWriter;
+import org.eclipse.jdt.core.compiler.InvalidInputException;
+
+import java.io.PrintWriter;
+
+import junit.framework.TestCase;
+
+/**
+ * Some black-box test is happening here.
+ */
+public class AjdtCommandTestCase extends TestCase {
+
+ private StreamPrintWriter outputWriter = new StreamPrintWriter(new PrintWriter(System.out));
+ private AjdtCommand command = new AjdtCommand();
+ private MessageWriter messageWriter = new MessageWriter(outputWriter, false);
+
+ public AjdtCommandTestCase(String name) {
+ super(name);
+// command.buildArgParser.out = outputWriter;
+ }
+
+ public void testIncrementalOption() throws InvalidInputException {
+ AjBuildConfig config = command.genBuildConfig(new String[] { "-incremental" }, messageWriter);
+
+ assertTrue(
+ "didn't specify source root",
+ outputWriter.getContents().indexOf("specify a source root") != -1);
+
+ outputWriter.flushBuffer();
+ config = command.genBuildConfig(
+ new String[] { "-incremental", "-sourceroots", "testdata/src1" },
+ messageWriter);
+
+ assertTrue(
+ outputWriter.getContents(),
+ outputWriter.getContents().equals(""));
+
+ outputWriter.flushBuffer();
+ config = command.genBuildConfig(
+ new String[] { "-incremental", "testdata/src1/Hello.java" },
+ messageWriter);
+
+ assertTrue(
+ "specified a file",
+ outputWriter.getContents().indexOf("can not directly specify files") != -1); ;
+ }
+
+ public void testBadOptionAndUsagePrinting() throws InvalidInputException {
+ try {
+ command.genBuildConfig(new String[] { "-mubleBadOption" }, messageWriter);
+ } catch (AbortException ae) { }
+
+ assertTrue(
+ outputWriter.getContents() + " contains? " + "Usage",
+ outputWriter.getContents().indexOf("Usage") != -1);
+
+ }
+
+ public void testHelpUsagePrinting() {
+ try {
+ command.genBuildConfig(new String[] { "-help" }, messageWriter);
+ } catch (AbortException ae) { }
+ assertTrue(
+ outputWriter.getContents() + " contains? " + "Usage",
+ outputWriter.getContents().indexOf("Usage") != -1);
+ }
+
+ public void testVersionOutput() throws InvalidInputException {
+ try {
+ command.genBuildConfig(new String[] { "-version" }, messageWriter);
+ } catch (AbortException ae) { }
+ assertTrue(
+ "version output",
+ outputWriter.getContents().indexOf("AspectJ Compiler") != -1);
+ }
+
+ public void testNonExistingLstFile() {
+ command.genBuildConfig(new String[] { "@mumbleDoesNotExist" }, messageWriter);
+
+ assertTrue(
+ outputWriter.getContents(),
+ outputWriter.getContents().indexOf("file does not exist") != -1);
+ }
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ }
+
+ protected void tearDown() throws Exception {
+ super.tearDown();
+ outputWriter.flushBuffer();
+ }
+}
diff --git a/org.aspectj.ajdt.core/testsrc/org/aspectj/ajdt/ajc/BuildArgParserTestCase.java b/org.aspectj.ajdt.core/testsrc/org/aspectj/ajdt/ajc/BuildArgParserTestCase.java
new file mode 100644
index 000000000..e2d23f7a1
--- /dev/null
+++ b/org.aspectj.ajdt.core/testsrc/org/aspectj/ajdt/ajc/BuildArgParserTestCase.java
@@ -0,0 +1,401 @@
+/* *******************************************************************
+ * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC).
+ * All rights reserved.
+ * This program and the accompanying materials are made available
+ * under the terms of the Common Public License v1.0
+ * which accompanies this distribution and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * Xerox/PARC initial implementation
+ * ******************************************************************/
+
+package org.aspectj.ajdt.ajc;
+
+import org.aspectj.ajdt.internal.core.builder.AjBuildConfig;
+import org.aspectj.ajdt.internal.core.builder.AjCompilerOptions;
+import org.aspectj.bridge.MessageWriter;
+import org.aspectj.testing.util.TestUtil;
+import org.eclipse.jdt.core.compiler.InvalidInputException;
+import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.List;
+
+import junit.framework.TestCase;
+
+/**
+ * Some black-box test is happening here.
+ */
+public class BuildArgParserTestCase extends TestCase {
+
+ private BuildArgParser parser = new BuildArgParser();
+ private static final String TEST_DIR = "testdata" + File.separator + "ajc" + File.separator;
+ private MessageWriter messageWriter = new MessageWriter(new PrintWriter(System.out), false);
+
+ public BuildArgParserTestCase(String name) {
+ super(name);
+ }
+
+ public void testDefaultClasspathAndTargetCombo() throws InvalidInputException {
+ String ENTRY = "1.jar;2.jar";
+ final String classpath = System.getProperty("java.class.path");
+ try {
+ System.setProperty("java.class.path", ENTRY); // see finally below
+ AjBuildConfig config = parser.genBuildConfig(new String[] { }, messageWriter);
+ String err = parser.getOtherMessages(true);
+ assertTrue(err, null == err);
+ assertTrue(
+ config.getClasspath().toString(),
+ config.getClasspath().contains("1.jar"));
+ assertTrue(
+ config.getClasspath().toString(),
+ config.getClasspath().contains("2.jar"));
+
+ config = parser.genBuildConfig(new String[] { "-1.3" }, messageWriter);
+ err = parser.getOtherMessages(true);
+ assertTrue(err, null == err);
+ assertTrue(
+ config.getClasspath().toString(),
+ config.getClasspath().contains("1.jar"));
+ assertTrue(
+ config.getClasspath().toString(),
+ config.getClasspath().contains("2.jar"));
+
+ config = parser.genBuildConfig(new String[] { "-1.3" }, messageWriter);
+ err = parser.getOtherMessages(true);
+ assertTrue(err, null == err);
+ assertTrue(
+ config.getClasspath().toString(),
+ config.getClasspath().contains("1.jar"));
+ assertTrue(
+ config.getClasspath().toString(),
+ config.getClasspath().contains("2.jar"));
+
+ config = parser.genBuildConfig(new String[] {
+ "-classpath", ENTRY, "-1.4" }, messageWriter);
+ err = parser.getOtherMessages(true);
+ assertTrue("expected errors for missing jars", null != err);
+ assertTrue(
+ config.getClasspath().toString(),
+ config.getClasspath().contains("1.jar"));
+ assertTrue(
+ config.getClasspath().toString(),
+ config.getClasspath().contains("2.jar"));
+
+ } finally {
+ // do finally to avoid messing up classpath for other tests
+ System.setProperty("java.class.path", classpath);
+ String setPath = System.getProperty("java.class.path");
+ String m = "other tests will fail - classpath not reset";
+ assertEquals(m, classpath, setPath);
+ }
+ }
+
+ public void testAjOptions() throws InvalidInputException {
+ AjBuildConfig config = parser.genBuildConfig(new String[] { "-Xlint" }, messageWriter);
+
+ assertTrue(
+ "default options",
+ config.getAjOptions().get(AjCompilerOptions.OPTION_Xlint).equals(
+ CompilerOptions.GENERATE));
+ }
+
+ public void testAspectpath() throws InvalidInputException {
+ final String SOURCE_JAR = "testdata/testclasses.jar";
+ final String SOURCE_JARS = "testdata/testclasses.jar" + File.pathSeparator
+ + "../bcweaver/testdata/tracing.jar" + File.pathSeparator
+ + "../bcweaver/testdata/dummyAspect.jar";
+ AjBuildConfig config = parser.genBuildConfig(new String[] {
+ "-aspectpath", SOURCE_JAR },
+ messageWriter);
+
+ assertTrue(((File)config.getAspectpath().get(0)).getName(), ((File)config.getAspectpath().get(0)).getName().equals("testclasses.jar"));
+
+ config = parser.genBuildConfig(new String[] {
+ "-aspectpath", SOURCE_JARS },
+ messageWriter);
+ assertTrue("size", + config.getAspectpath().size() == 3);
+ }
+
+ public void testInJars() throws InvalidInputException {
+ final String SOURCE_JAR = "testdata/testclasses.jar";
+ final String SOURCE_JARS = "testdata/testclasses.jar" + File.pathSeparator
+ + "../bcweaver/testdata/tracing.jar" + File.pathSeparator
+ + "../bcweaver/testdata/dummyAspect.jar";
+ AjBuildConfig config = parser.genBuildConfig(new String[] {
+ "-injars", SOURCE_JAR },
+ messageWriter);
+ //XXX don't let this remain in both places in beta1
+ assertTrue(
+ "" + config.getAjOptions().get(AjCompilerOptions.OPTION_InJARs),
+ config.getAjOptions().get(AjCompilerOptions.OPTION_InJARs).equals(CompilerOptions.PRESERVE));
+ assertTrue(((File)config.getInJars().get(0)).getName(), ((File)config.getInJars().get(0)).getName().equals("testclasses.jar"));
+
+ config = parser.genBuildConfig(new String[] {
+ "-injars", SOURCE_JARS },
+ messageWriter);
+ assertTrue("size", + config.getInJars().size() == 3);
+ }
+
+ public void testBadInJars() throws InvalidInputException {
+ final String SOURCE_JARS = "testdata/testclasses.jar" + File.pathSeparator + "b.far" + File.pathSeparator + "c.jar";
+ AjBuildConfig config = parser.genBuildConfig(new String[] {
+ "-injars", SOURCE_JARS },
+ messageWriter);
+ assertTrue("size: " + config.getInJars().size(), config.getInJars().size() == 1);
+ }
+
+ public void testMultipleSourceRoots() throws InvalidInputException {
+ final String SRCROOT_1 = "testdata/src1/p1";
+ final String SRCROOT_2 = "testdata/ajc";
+ AjBuildConfig config = parser.genBuildConfig(new String[] {
+ "-sourceroots", SRCROOT_1 + File.pathSeparator + SRCROOT_2 },
+ messageWriter);
+
+ assertEquals(new File(SRCROOT_1).getAbsolutePath(), ((File)config.getSourceRoots().get(0)).getAbsolutePath());
+
+ Collection expectedFiles = Arrays.asList(new File[] {
+ new File(SRCROOT_1+File.separator+"A.java").getAbsoluteFile(),
+ new File(SRCROOT_1+File.separator+"Foo.java").getAbsoluteFile(),
+ new File(SRCROOT_2+File.separator+"A.java").getAbsoluteFile(),
+ new File(SRCROOT_2+File.separator+"B.java").getAbsoluteFile(),
+ new File(SRCROOT_2+File.separator+"X.aj").getAbsoluteFile(),
+ new File(SRCROOT_2+File.separator+"Y.aj").getAbsoluteFile(),
+ new File(SRCROOT_2+File.separator+"pkg"+File.separator+"Hello.java").getAbsoluteFile(),
+ });
+
+ //System.out.println(config.getFiles());
+
+ TestUtil.assertSetEquals(expectedFiles, config.getFiles());
+ }
+
+ public void testSourceRootDir() throws InvalidInputException {
+ final String SRCROOT = "testdata/ajc";
+ AjBuildConfig config = parser.genBuildConfig(new String[] {
+ "-sourceroots", SRCROOT },
+ messageWriter);
+
+ assertEquals(new File(SRCROOT).getAbsolutePath(), ((File)config.getSourceRoots().get(0)).getAbsolutePath());
+
+ Collection expectedFiles = Arrays.asList(new File[] {
+ new File(SRCROOT+File.separator+"A.java").getAbsoluteFile(),
+ new File(SRCROOT+File.separator+"B.java").getAbsoluteFile(),
+ new File(SRCROOT+File.separator+"X.aj").getAbsoluteFile(),
+ new File(SRCROOT+File.separator+"Y.aj").getAbsoluteFile(),
+ new File(SRCROOT+File.separator+"pkg"+File.separator+"Hello.java").getAbsoluteFile(),
+ });
+
+ //System.out.println(config.getFiles());
+
+ TestUtil.assertSetEquals(expectedFiles, config.getFiles());
+ }
+
+ public void testBadSourceRootDir() throws InvalidInputException {
+ AjBuildConfig config = parser.genBuildConfig(new String[] {
+ "-sourceroots",
+ "testdata/mumbleDoesNotExist;testdata/ajc" },
+ messageWriter);
+
+ assertTrue(config.getSourceRoots().toString(), config.getSourceRoots().size() == 1);
+
+ config = parser.genBuildConfig(new String[] {
+ "-sourceroots" },
+ messageWriter);
+
+ assertTrue("" + config.getSourceRoots(), config.getSourceRoots().size() == 0);
+
+ }
+
+ //??? we've decided not to make this an error
+ public void testSourceRootDirWithFiles() throws InvalidInputException {
+ final String SRCROOT = "testdata/ajc/pkg";
+ AjBuildConfig config = parser.genBuildConfig(new String[] {
+ "-sourceroots", SRCROOT, "testdata/src1/A.java"},
+ messageWriter);
+
+ assertEquals(new File(SRCROOT).getAbsolutePath(), ((File)config.getSourceRoots().get(0)).getAbsolutePath());
+
+ Collection expectedFiles = Arrays.asList(new File[] {
+ new File(SRCROOT+File.separator+"Hello.java").getAbsoluteFile(),
+ new File("testdata"+File.separator+"src1"+File.separator+"A.java").getAbsoluteFile(),
+ });
+
+ TestUtil.assertSetEquals(expectedFiles, config.getFiles());
+
+ }
+
+ public void testExtDirs() throws InvalidInputException {
+ final String DIR = "testdata";
+ AjBuildConfig config = parser.genBuildConfig(new String[] {
+ "-extdirs", DIR },
+ messageWriter);
+ assertTrue(config.getClasspath().toString(), config.getClasspath().contains(
+ new File(DIR + File.separator + "testclasses.jar").getAbsolutePath()
+ ));
+ }
+
+ public void testBootclasspath() throws InvalidInputException {
+ final String PATH = "mumble/rt.jar";
+ AjBuildConfig config = parser.genBuildConfig(new String[] {
+ "-bootclasspath", PATH },
+ messageWriter);
+ assertTrue(config.getClasspath().toString(), config.getClasspath().get(0).equals(PATH));
+
+ config = parser.genBuildConfig(new String[] {
+ },
+ messageWriter);
+ assertTrue(config.getClasspath().toString(), !config.getClasspath().get(0).equals(PATH));
+ }
+
+ public void testOutputJar() throws InvalidInputException {
+ final String OUT_JAR = "testdata/testclasses.jar";
+
+ AjBuildConfig config = parser.genBuildConfig(new String[] {
+ "-outjar", OUT_JAR },
+ messageWriter);
+
+ //XXX don't let this remain in both places in beta1
+ assertTrue(
+ "will generate: " + config.getAjOptions().get(AjCompilerOptions.OPTION_OutJAR),
+ config.getAjOptions().get(AjCompilerOptions.OPTION_OutJAR).equals(CompilerOptions.GENERATE));
+ assertTrue(
+ "testclasses jar: " + config.getOutputJar().getName(),
+ config.getOutputJar().getAbsolutePath().equals(new File(OUT_JAR).getAbsolutePath()));
+
+ File nonExistingJar = new File("testdata/mumbleDoesNotExist.jar");
+ config = parser.genBuildConfig(new String[] {
+ "-outjar", nonExistingJar.getAbsolutePath() },
+ messageWriter);
+ assertTrue(
+ "testclasses jar: " + config.getOutputJar().getName(),
+ config.getOutputJar().getAbsolutePath().equals(nonExistingJar.getAbsolutePath()));
+
+ nonExistingJar.delete();
+ }
+
+ //XXX shouldn't need -1.4 to get this to pass
+ public void testCombinedOptions() throws InvalidInputException {
+ AjBuildConfig config = parser.genBuildConfig(new String[] { "-Xlint", "-target", "1.4", "-1.4" }, messageWriter);
+ String TARGET = "1.4";
+ assertTrue(
+ "target set",
+ config.getJavaOptions().get(CompilerOptions.OPTION_TargetPlatform).equals(TARGET));
+
+ assertTrue(
+ "Xlint option set",
+ config.getAjOptions().get(AjCompilerOptions.OPTION_Xlint).equals(
+ CompilerOptions.GENERATE));
+ }
+
+ public void testOutputDirectorySetting() throws InvalidInputException {
+ AjBuildConfig config = parser.genBuildConfig(new String[] { "-d", TEST_DIR }, messageWriter);
+
+ assertTrue(
+ new File(config.getOutputDir().getPath()).getAbsolutePath() + " ?= " +
+ new File(TEST_DIR).getAbsolutePath(),
+ config.getOutputDir().getAbsolutePath().equals((new File(TEST_DIR)).getAbsolutePath()));
+ }
+
+ public void testClasspathSetting() throws InvalidInputException {
+ String ENTRY = "1.jar;2.jar";
+ AjBuildConfig config = parser.genBuildConfig(new String[] { "-classpath", ENTRY }, messageWriter);
+
+ assertTrue(
+ config.getClasspath().toString(),
+ config.getClasspath().contains("1.jar"));
+
+ assertTrue(
+ config.getClasspath().toString(),
+ config.getClasspath().contains("2.jar"));
+ }
+
+ public void testArgInConfigFile() throws InvalidInputException {
+ String FILE_PATH = "@" + TEST_DIR + "configWithArgs.lst";
+ String OUT_PATH = "bin";
+ AjBuildConfig config = parser.genBuildConfig(new String[] { FILE_PATH }, messageWriter);
+
+ assertNotNull(config);
+ File outputDir = config.getOutputDir();
+ assertNotNull(outputDir);
+ assertEquals(outputDir.getPath(), OUT_PATH);
+ }
+
+ public void testXlint() throws InvalidInputException {
+ AjdtCommand command = new AjdtCommand();
+ AjBuildConfig config = parser.genBuildConfig(new String[] {"-Xlint"}, messageWriter);
+ assertTrue("", config.getLintMode().equals(AjBuildConfig.AJLINT_DEFAULT));
+ config = parser.genBuildConfig(new String[] {"-Xlint:warn"}, messageWriter);
+ assertTrue("", config.getLintMode().equals(AjBuildConfig.AJLINT_WARN));
+ config = parser.genBuildConfig(new String[] {"-Xlint:error"}, messageWriter);
+ assertTrue("", config.getLintMode().equals(AjBuildConfig.AJLINT_ERROR));
+ config = parser.genBuildConfig(new String[] {"-Xlint:ignore"}, messageWriter);
+ assertTrue("", config.getLintMode().equals(AjBuildConfig.AJLINT_INGORE));
+ }
+
+ public void testXlintfile() throws InvalidInputException {
+ String lintFile = "testdata/lintspec.properties";
+ String badLintFile = "lint.props";
+ AjBuildConfig config = parser.genBuildConfig(new String[] {"-Xlintfile", lintFile}, messageWriter);
+ assertTrue(new File(lintFile).exists());
+ assertTrue(config.getLintSpecFile().getAbsolutePath(), config.getLintSpecFile().getAbsolutePath().equals(new File(lintFile).getAbsolutePath()));
+ }
+
+ public void testOptions() throws InvalidInputException {
+ AjdtCommand command = new AjdtCommand();
+ String TARGET = "1.4";
+ AjBuildConfig config = parser.genBuildConfig(new String[] {"-target", TARGET, "-source", TARGET}, messageWriter);
+ assertTrue(
+ "target set",
+ config.getJavaOptions().get(CompilerOptions.OPTION_TargetPlatform).equals(TARGET));
+ assertTrue(
+ "source set",
+ config.getJavaOptions().get(CompilerOptions.OPTION_Compliance).equals(CompilerOptions.VERSION_1_4));
+ }
+
+ public void testLstFileExpansion() throws IOException, FileNotFoundException, InvalidInputException {
+ String FILE_PATH = TEST_DIR + "config.lst";
+ String SOURCE_PATH_1 = "A.java";
+ String SOURCE_PATH_2 = "B.java";
+
+ File f = new File(FILE_PATH);
+
+ AjBuildConfig config = parser.genBuildConfig(new String[] { "@" + FILE_PATH }, messageWriter);
+ List resultList = config.getFiles();
+
+ assertTrue("correct number of files", resultList.size() == 2);
+ assertTrue(resultList.toString() + new File(TEST_DIR + SOURCE_PATH_1).getAbsoluteFile(),
+ resultList.contains(new File(TEST_DIR + SOURCE_PATH_1).getAbsoluteFile()));
+ assertTrue(resultList.toString() + SOURCE_PATH_2,
+ resultList.contains(new File(TEST_DIR + SOURCE_PATH_2).getAbsoluteFile()));
+ }
+
+
+ //??? do we need to remove this limitation
+// public void testArgInConfigFileAndRelativizingPathParam() throws InvalidInputException {
+// String FILE_PATH = "@" + TEST_DIR + "configWithArgs.lst";
+// String OUT_PATH = TEST_DIR + "bin";
+// AjBuildConfig config = parser.genBuildConfig(new String[] { FILE_PATH });
+//
+// assertTrue(
+// config.getOutputDir().getPath() + " ?= " + OUT_PATH,
+// config.getOutputDir().getAbsolutePath().equals((new File(OUT_PATH)).getAbsolutePath()));
+// }
+
+ public void testAjFileInclusion() throws InvalidInputException {
+ parser.genBuildConfig(new String[] { TEST_DIR + "X.aj", TEST_DIR + "Y.aj"}, messageWriter);
+ }
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ }
+
+ protected void tearDown() throws Exception {
+ super.tearDown();
+ }
+}
diff --git a/org.aspectj.ajdt.core/testsrc/org/aspectj/ajdt/ajc/ConsoleMessageHandlerTestCase.java b/org.aspectj.ajdt.core/testsrc/org/aspectj/ajdt/ajc/ConsoleMessageHandlerTestCase.java
new file mode 100644
index 000000000..c359f91bb
--- /dev/null
+++ b/org.aspectj.ajdt.core/testsrc/org/aspectj/ajdt/ajc/ConsoleMessageHandlerTestCase.java
@@ -0,0 +1,62 @@
+/* *******************************************************************
+ * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC).
+ * All rights reserved.
+ * This program and the accompanying materials are made available
+ * under the terms of the Common Public License v1.0
+ * which accompanies this distribution and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * Xerox/PARC initial implementation
+ * ******************************************************************/
+
+package org.aspectj.ajdt.ajc;
+
+import java.io.PrintWriter;
+
+import junit.framework.TestCase;
+import org.aspectj.bridge.*;
+import org.aspectj.bridge.Message;
+import org.aspectj.util.StreamPrintWriter;
+
+/**
+ * @author Mik Kersten
+ */
+public class ConsoleMessageHandlerTestCase extends TestCase {
+
+ /**
+ * Constructor for ConsoleWriterTestCase.
+ * @param name
+ */
+ public ConsoleMessageHandlerTestCase(String name) {
+ super(name);
+ }
+
+ public void testIgnoringInfoMessages() {
+ testOutput(false);
+ }
+
+ public void testHandlingInfoMessages() {
+ testOutput(true);
+ }
+
+ private void testOutput(boolean verboseMode) {
+ //XXX update to new MessageHandler
+// final String MESSAGE = "test;";
+//
+// StreamPrintWriter output = new StreamPrintWriter(new PrintWriter(System.out));
+// ConsoleMessageHandler writer = new ConsoleMessageHandler(output);
+// if (!verboseMode) writer.ignore(IMessage.INFO);
+//
+// writer.handleMessage(new Message(MESSAGE, Message.INFO, null, null));
+// if (verboseMode) {
+// assertTrue("message=" + output.getContents(), output.getContents().equals(MESSAGE + "\n"));
+// } else {
+// assertTrue("message=" + output.getContents(), output.getContents().equals(""));
+// }
+//
+// output.flushBuffer();
+// writer.handleMessage(new Message(MESSAGE, Message.ERROR, null, null));
+// assertTrue(output.getContents(), output.getContents().equals(MESSAGE + "\n"));
+ }
+}
diff --git a/org.aspectj.ajdt.core/testsrc/org/aspectj/ajdt/internal/compiler/batch/AjdtBatchTests.java b/org.aspectj.ajdt.core/testsrc/org/aspectj/ajdt/internal/compiler/batch/AjdtBatchTests.java
new file mode 100644
index 000000000..025e7c766
--- /dev/null
+++ b/org.aspectj.ajdt.core/testsrc/org/aspectj/ajdt/internal/compiler/batch/AjdtBatchTests.java
@@ -0,0 +1,39 @@
+/* *******************************************************************
+ * Copyright (c) 1999-2001 Xerox Corporation,
+ * 2002 Palo Alto Research Center, Incorporated (PARC).
+ * All rights reserved.
+ * This program and the accompanying materials are made available
+ * under the terms of the Common Public License v1.0
+ * which accompanies this distribution and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * Xerox/PARC initial implementation
+ * ******************************************************************/
+
+
+package org.aspectj.ajdt.internal.compiler.batch;
+
+import junit.framework.*;
+
+public class AjdtBatchTests extends TestCase {
+
+ public static Test suite() {
+ TestSuite suite = new TestSuite(AjdtBatchTests.class.getName());
+ // Abstract superclass
+ //suite.addTestSuite(CommandTestCase.class);
+ //$JUnit-BEGIN$
+ suite.addTestSuite(BasicCommandTestCase.class);
+ suite.addTestSuite(BinaryFormsTestCase.class);
+ suite.addTestSuite(CompileAndRunTestCase.class);
+ suite.addTestSuite(ImageTestCase.class);
+ suite.addTestSuite(MultipleCompileTestCase.class);
+ // XXX suite.addTestSuite(VerifyWeaveTestCase.class);
+ //suite.addTestSuite(WorkingCommandTestCase.class);
+ //$JUnit-END$
+ return suite;
+ }
+
+ public AjdtBatchTests(String name) { super(name); }
+
+}
diff --git a/org.aspectj.ajdt.core/testsrc/org/aspectj/ajdt/internal/compiler/batch/BasicCommandTestCase.java b/org.aspectj.ajdt.core/testsrc/org/aspectj/ajdt/internal/compiler/batch/BasicCommandTestCase.java
new file mode 100644
index 000000000..9b5a69fb6
--- /dev/null
+++ b/org.aspectj.ajdt.core/testsrc/org/aspectj/ajdt/internal/compiler/batch/BasicCommandTestCase.java
@@ -0,0 +1,103 @@
+/* *******************************************************************
+ * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC).
+ * All rights reserved.
+ * This program and the accompanying materials are made available
+ * under the terms of the Common Public License v1.0
+ * which accompanies this distribution and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * Xerox/PARC initial implementation
+ * ******************************************************************/
+
+package org.aspectj.ajdt.internal.compiler.batch;
+
+import java.util.*;
+
+import org.aspectj.ajdt.ajc.*;
+import org.aspectj.bridge.*;
+
+import junit.framework.*;
+
+/**
+ * @author hugunin
+ *
+ * To change this generated comment edit the template variable "typecomment":
+ * Window>Preferences>Java>Templates.
+ * To enable and disable the creation of type comments go to
+ * Window>Preferences>Java>Code Generation.
+ */
+public class BasicCommandTestCase extends CommandTestCase {
+
+ /**
+ * Constructor for CommandTestCase.
+ * @param name
+ */
+ public BasicCommandTestCase(String name) {
+ super(name);
+ }
+
+ public void testA() {
+ checkCompile("src1/A.java", NO_ERRORS);
+ }
+
+ public void testA1() {
+ checkCompile("src1/A1.java", NO_ERRORS);
+ }
+
+ public void testBadA() {
+ checkCompile("src1/BadA.java", new int[] {7, 8});
+ }
+
+ public void testHello() {
+ checkCompile("src1/Hello.java", NO_ERRORS);
+ }
+
+ public void testBadHello() {
+ checkCompile("src1/BadHello.java", new int[] {5});
+ }
+
+ public void testMissingHello() {
+ checkCompile("src1/MissingHello.java", TOP_ERROR);
+ }
+
+ public void testBadBinding() {
+ checkCompile("src1/BadBinding.java", new int[] {2, 4, 8, 10, 13, 16, 19});
+ }
+ public void testThisAndModifiers() {
+ checkCompile("src1/ThisAndModifiers.java", NO_ERRORS);
+ }
+ public void testDeclares() {
+ checkCompile("src1/Declares.java", new int[] {3});
+ }
+
+ public void testDeclareWarning() {
+ checkCompile("src1/DeclareWarning.java", NO_ERRORS);
+ }
+
+
+ public void testP1() {
+ checkCompile("src1/p1/Foo.java", NO_ERRORS);
+ }
+
+ public void testUnimplementedSyntax() {
+ checkCompile("src1/UnimplementedSyntax.java",
+ new int[] {5, 15, 16, 23});
+ }
+ public void testXlintWarn() {
+ checkCompile("src1/Xlint.java", NO_ERRORS);
+ }
+ public void testXlintError() {
+ List args = new ArrayList();
+
+ args.add("-d");
+ args.add("out");
+
+ args.add("-classpath");
+ args.add("../runtime/bin;../lib/junit/junit.jar;../testing-client/bin");
+ args.add("-Xlint:error");
+ args.add("testdata/src1/Xlint.java");
+
+ runCompiler(args, new int[] {2});
+ }
+}
diff --git a/org.aspectj.ajdt.core/testsrc/org/aspectj/ajdt/internal/compiler/batch/BcweaverJarMaker.java b/org.aspectj.ajdt.core/testsrc/org/aspectj/ajdt/internal/compiler/batch/BcweaverJarMaker.java
new file mode 100644
index 000000000..7c232aa96
--- /dev/null
+++ b/org.aspectj.ajdt.core/testsrc/org/aspectj/ajdt/internal/compiler/batch/BcweaverJarMaker.java
@@ -0,0 +1,90 @@
+/* *******************************************************************
+ * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC).
+ * All rights reserved.
+ * This program and the accompanying materials are made available
+ * under the terms of the Common Public License v1.0
+ * which accompanies this distribution and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * Xerox/PARC initial implementation
+ * ******************************************************************/
+
+package org.aspectj.ajdt.internal.compiler.batch;
+
+import java.io.IOException;
+import java.util.*;
+import java.util.ArrayList;
+
+public class BcweaverJarMaker {
+
+ public BcweaverJarMaker() {
+ super();
+ }
+
+ public static void main(String[] args) throws IOException {
+ makeJar0();
+ makeJar1();
+ makeJar1a();
+ makeJar2();
+ }
+
+ public static void makeJar0() throws IOException {
+ List args = new ArrayList();
+ args.add("-outjar");
+ args.add("../bcweaver/testdata/tracing.jar");
+
+ args.add("-classpath");
+ args.add("../runtime/bin");
+
+ args.add("testdata/src1/Trace.java");
+ args.add("testdata/src1/MyTrace.java");
+
+ CommandTestCase.runCompiler(args, CommandTestCase.NO_ERRORS);
+ }
+
+ public static void makeJar1() throws IOException {
+ List args = new ArrayList();
+ args.add("-outjar");
+ args.add("../bcweaver/testdata/megatrace.jar");
+
+ args.add("-classpath");
+ args.add("../runtime/bin");
+
+ args.add("testdata/src1/trace/MegaTrace.java");
+ args.add("testdata/src1/trace/ExecTrace.java");
+
+ CommandTestCase.runCompiler(args, CommandTestCase.NO_ERRORS);
+ }
+
+
+ public static void makeJar1a() throws IOException {
+ List args = new ArrayList();
+ args.add("-outjar");
+ args.add("../bcweaver/testdata/megatraceNoweave.jar");
+
+ args.add("-noweave");
+
+ args.add("-classpath");
+ args.add("../runtime/bin");
+
+ args.add("testdata/src1/trace/MegaTrace.java");
+ args.add("testdata/src1/trace/ExecTrace.java");
+
+ CommandTestCase.runCompiler(args, CommandTestCase.NO_ERRORS);
+ }
+
+
+ public static void makeJar2() throws IOException {
+ List args = new ArrayList();
+ args.add("-outjar");
+ args.add("../bcweaver/testdata/dummyAspect.jar");
+
+ args.add("-classpath");
+ args.add("../runtime/bin");
+
+ args.add("testdata/src1/DummyAspect.java");
+
+ CommandTestCase.runCompiler(args, CommandTestCase.NO_ERRORS);
+ }
+}
diff --git a/org.aspectj.ajdt.core/testsrc/org/aspectj/ajdt/internal/compiler/batch/BinaryFormsTestCase.java b/org.aspectj.ajdt.core/testsrc/org/aspectj/ajdt/internal/compiler/batch/BinaryFormsTestCase.java
new file mode 100644
index 000000000..4fc63b0dc
--- /dev/null
+++ b/org.aspectj.ajdt.core/testsrc/org/aspectj/ajdt/internal/compiler/batch/BinaryFormsTestCase.java
@@ -0,0 +1,52 @@
+/* *******************************************************************
+ * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC).
+ * All rights reserved.
+ * This program and the accompanying materials are made available
+ * under the terms of the Common Public License v1.0
+ * which accompanies this distribution and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * Xerox/PARC initial implementation
+ * ******************************************************************/
+
+package org.aspectj.ajdt.internal.compiler.batch;
+
+import java.io.IOException;
+import java.util.*;
+
+
+public class BinaryFormsTestCase extends CommandTestCase {
+
+ public BinaryFormsTestCase(String name) {
+ super(name);
+ }
+
+ public void testDummy() {}
+
+
+ public void XXXtestJar1() throws IOException {
+ List args = new ArrayList();
+ args.add("-outjar");
+ args.add("out/megatrace.jar");
+
+ args.add("-classpath");
+ args.add("../runtime/bin");
+
+ args.add("testdata/src1/trace/MegaTrace.java");
+ args.add("testdata/src1/trace/ExecTrace.java");
+
+ CommandTestCase.runCompiler(args, CommandTestCase.NO_ERRORS);
+
+ args = new ArrayList();
+ args.add("-aspectpath");
+ args.add("out/megatrace.jar");
+
+ args.add("-classpath");
+ args.add("../runtime/bin");
+
+ args.add("testdata/src1/tracep1/TraceTest.java");
+
+ CommandTestCase.runCompiler(args, CommandTestCase.NO_ERRORS);
+ }
+}
diff --git a/org.aspectj.ajdt.core/testsrc/org/aspectj/ajdt/internal/compiler/batch/CommandTestCase.java b/org.aspectj.ajdt.core/testsrc/org/aspectj/ajdt/internal/compiler/batch/CommandTestCase.java
new file mode 100644
index 000000000..cd9a440de
--- /dev/null
+++ b/org.aspectj.ajdt.core/testsrc/org/aspectj/ajdt/internal/compiler/batch/CommandTestCase.java
@@ -0,0 +1,160 @@
+/* *******************************************************************
+ * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC).
+ * All rights reserved.
+ * This program and the accompanying materials are made available
+ * under the terms of the Common Public License v1.0
+ * which accompanies this distribution and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * Xerox/PARC initial implementation
+ * ******************************************************************/
+
+package org.aspectj.ajdt.internal.compiler.batch;
+
+import org.aspectj.ajdt.ajc.AjdtCommand;
+import org.aspectj.bridge.ICommand;
+import org.aspectj.bridge.IMessage;
+import org.aspectj.bridge.IMessageHandler;
+import org.aspectj.bridge.MessageHandler;
+
+import java.io.*;
+import java.io.File;
+import java.io.IOException;
+import java.util.*;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.List;
+
+import org.aspectj.ajdt.ajc.*;
+import org.aspectj.weaver.*;
+import org.aspectj.weaver.bcel.LazyClassGen;
+import org.aspectj.bridge.*;
+
+import junit.framework.*;
+import org.aspectj.weaver.*;
+
+public abstract class CommandTestCase extends TestCase {
+
+ /**
+ * Constructor for CommandTestCase.
+ * @param name
+ */
+ public CommandTestCase(String name) {
+ super(name);
+ }
+
+ public static final int[] NO_ERRORS = new int[0];
+ public static final int[] TOP_ERROR = new int[0];
+
+
+ public static void checkCompile(String source, int[] expectedErrors) {
+ List args = new ArrayList();
+ args.add("-verbose");
+
+ args.add("-d");
+ args.add("out");
+
+ args.add("-classpath");
+ args.add("../runtime/bin;../lib/junit/junit.jar");
+
+ args.add("-g"); //XXX need this to get sourcefile and line numbers, shouldn't
+
+ args.add("testdata/" + source);
+
+ runCompiler(args, expectedErrors);
+ }
+
+ public void checkMultipleCompile(String source) throws InterruptedException {
+ List args = new ArrayList();
+ args.add("-verbose");
+
+ args.add("-d");
+ args.add("out");
+
+ args.add("-classpath");
+ args.add("../runtime/bin");
+
+ args.add("testdata/" + source);
+
+ ICommand compiler = runCompiler(args, NO_ERRORS);
+ Thread.sleep(100);
+
+ rerunCompiler(compiler);
+ }
+
+ public void rerunCompiler(ICommand command) {
+ MessageHandler myHandler = new MessageHandler();
+ List recompiledFiles = new ArrayList();
+ if (!command.repeatCommand(myHandler)) {
+ assertTrue("recompile failed", false);
+ }
+ assertEquals(0, myHandler.numMessages(IMessage.ERROR, true));
+ }
+
+
+
+ public static ICommand runCompiler(List args, int[] expectedErrors) {
+ ICommand command = new AjdtCommand();
+ MessageHandler myHandler = new MessageHandler();
+ myHandler.setInterceptor(org.aspectj.tools.ajc.Main.MessagePrinter.TERSE);
+ command.runCommand((String[])args.toArray(new String[args.size()]), myHandler);
+
+// System.out.println("errors: " + Arrays.asList(myHandler.getErrors()));
+// System.out.println("warnings: " + Arrays.asList(myHandler.getWarnings()));
+
+ int nErrors = myHandler.numMessages(IMessage.ERROR, IMessageHolder.EQUAL);
+ if (expectedErrors == NO_ERRORS) {
+ if (0 != nErrors) {
+ String s = ""+Arrays.asList(myHandler.getErrors());
+ assertTrue("unexpected errors: " + s, false);
+ }
+ } else if (expectedErrors == TOP_ERROR) { // ?? what is this?
+ assertTrue("expected error", nErrors > 0);
+ } else {
+ List errors = new ArrayList(Arrays.asList(myHandler.getErrors()));
+ for (int i=0, len=expectedErrors.length; i < len; i++) {
+ int line = expectedErrors[i];
+ boolean found = false;
+ for (Iterator iter = errors.iterator(); iter.hasNext(); ) {
+ IMessage m = (IMessage)iter.next();
+ if (m.getISourceLocation() != null && m.getISourceLocation().getLine() == line) {
+ found = true;
+ iter.remove();
+ }
+ }
+ assertTrue("didn't find error on line " + line, found);
+ }
+ if (errors.size() > 0) {
+ assertTrue("didn't expect errors: " + errors, false);
+ }
+ }
+ return command;
+ }
+
+ public static void printGenerated(String path, String name) throws IOException {
+ String fullpath = "testdata/" + path;
+ LazyClassGen.disassemble(fullpath, name, System.out);
+ }
+
+ /** incremental test case adapter to JUnit */
+ public class IncCase extends IncrementalCase {
+ protected void fail(IMessageHandler handler, String mssg) {
+ assertTrue(mssg, false);
+ }
+ protected void message(
+ IMessage.Kind kind,
+ String mssg,
+ IMessageHandler handler) {
+ if ((kind == IMessage.FAIL) || (kind == IMessage.ABORT)) {
+ assertTrue(mssg, false);
+ } else {
+ System.err.println("IncCase " + kind + ": " + mssg); // XXX
+ }
+ super.message(kind, mssg, handler);
+ }
+
+ }
+
+}
diff --git a/org.aspectj.ajdt.core/testsrc/org/aspectj/ajdt/internal/compiler/batch/CompileAndRunTestCase.java b/org.aspectj.ajdt.core/testsrc/org/aspectj/ajdt/internal/compiler/batch/CompileAndRunTestCase.java
new file mode 100644
index 000000000..30a76570d
--- /dev/null
+++ b/org.aspectj.ajdt.core/testsrc/org/aspectj/ajdt/internal/compiler/batch/CompileAndRunTestCase.java
@@ -0,0 +1,90 @@
+/* *******************************************************************
+ * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC).
+ * All rights reserved.
+ * This program and the accompanying materials are made available
+ * under the terms of the Common Public License v1.0
+ * which accompanies this distribution and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * Xerox/PARC initial implementation
+ * ******************************************************************/
+
+package org.aspectj.ajdt.internal.compiler.batch;
+
+import java.io.IOException;
+
+import org.aspectj.testing.util.TestUtil;
+
+
+public class CompileAndRunTestCase extends CommandTestCase {
+
+ public CompileAndRunTestCase(String name) {
+ super(name);
+ }
+
+ public void testAround() throws IOException {
+ checkCompile("src1/AroundA.java", NO_ERRORS);
+ TestUtil.runMain("out", "AroundAMain");
+ }
+
+ public void testInterType() throws IOException {
+ checkCompile("src1/InterType.java", NO_ERRORS);
+ TestUtil.runMain("out", "InterType");
+ }
+
+ public void testInterTypeMethods() throws IOException {
+ checkCompile("src1/InterTypeMethods.java", NO_ERRORS);
+ TestUtil.runMain("out", "InterTypeMethods");
+ }
+
+ public void testIf() throws IOException {
+ CommandTestCase.checkCompile("src1/IfPcd.java", CommandTestCase.NO_ERRORS);
+ TestUtil.runMain("out", "IfPcd");
+ }
+
+ public void testDeclareParentsFail() throws IOException {
+ CommandTestCase.checkCompile("src1/ParentsFail.java", new int[] {3, 11, 19, 21});
+ }
+
+ public void testDeclareParents() throws IOException {
+ CommandTestCase.checkCompile("src1/Parents.java", CommandTestCase.NO_ERRORS);
+ TestUtil.runMain("out", "Parents");
+ }
+
+ public void testPerCflow() throws IOException {
+ CommandTestCase.checkCompile("src1/PerCflow.java", CommandTestCase.NO_ERRORS);
+ TestUtil.runMain("out", "PerCflow");
+ }
+
+ public void testPerObject() throws IOException {
+ CommandTestCase.checkCompile("src1/PerObject.java", CommandTestCase.NO_ERRORS);
+ TestUtil.runMain("out", "PerObject");
+ }
+
+ public void testDeclareSoft() throws IOException {
+ CommandTestCase.checkCompile("src1/DeclareSoft.java", CommandTestCase.NO_ERRORS);
+ TestUtil.runMain("out", "DeclareSoft");
+ }
+
+ public void testPrivileged() throws IOException {
+ CommandTestCase.checkCompile("src1/Privileged.java", CommandTestCase.NO_ERRORS);
+ TestUtil.runMain("out", "Privileged");
+ }
+
+ public void testHandler() throws IOException {
+ CommandTestCase.checkCompile("src1/Handler.java", CommandTestCase.NO_ERRORS);
+ TestUtil.runMain("out", "Handler");
+ }
+
+ public void testInterConstructors() throws IOException {
+ CommandTestCase.checkCompile("src1/InterTypeConstructors.java", CommandTestCase.NO_ERRORS);
+ TestUtil.runMain("out", "InterTypeConstructors");
+ }
+
+ public void testAroundA1() throws IOException {
+ CommandTestCase.checkCompile("src1/AroundA1.java", CommandTestCase.NO_ERRORS);
+ TestUtil.runMain("out", "AroundA1");
+ }
+
+}
diff --git a/org.aspectj.ajdt.core/testsrc/org/aspectj/ajdt/internal/compiler/batch/ImageTestCase.java b/org.aspectj.ajdt.core/testsrc/org/aspectj/ajdt/internal/compiler/batch/ImageTestCase.java
new file mode 100644
index 000000000..681c46668
--- /dev/null
+++ b/org.aspectj.ajdt.core/testsrc/org/aspectj/ajdt/internal/compiler/batch/ImageTestCase.java
@@ -0,0 +1,58 @@
+/* *******************************************************************
+ * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC).
+ * All rights reserved.
+ * This program and the accompanying materials are made available
+ * under the terms of the Common Public License v1.0
+ * which accompanies this distribution and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * Xerox/PARC initial implementation
+ * ******************************************************************/
+
+package org.aspectj.ajdt.internal.compiler.batch;
+
+import java.io.*;
+import java.io.File;
+import java.util.*;
+
+import junit.framework.*;
+
+import org.aspectj.ajdt.internal.core.builder.*;
+import org.aspectj.bridge.*;
+import org.aspectj.util.*;
+import org.aspectj.workbench.resources.*;
+import org.eclipse.core.internal.resources.*;
+import org.eclipse.core.resources.*;
+import org.eclipse.core.runtime.*;
+import org.eclipse.jdt.core.compiler.*;
+import org.eclipse.jdt.internal.compiler.*;
+import org.eclipse.jdt.internal.compiler.Compiler;
+import org.eclipse.jdt.internal.core.builder.*;
+
+public class ImageTestCase extends TestCase {
+
+
+
+ public ImageTestCase(String name) {
+ super(name);
+ }
+ public void testNothing() {}
+
+// public void test1() throws IOException, CoreException {
+// EclipseMessageHandler handler = new EclipseMessageHandler(new MessageHandler());
+// AjBuildManager config = new AjBuildManager(handler);
+//// config.setArgs(new String[] { "testdata/src1/BadHello.java" });
+//// config.setArgs(new String[] { "testdata/src1/A.java" });
+// List files = new ArrayList();
+// files.add(new File("testdata/src1/A.java"));
+// config.getBuildConfig().setFiles(files);
+//
+// SimpleBatchBuilder builder = new SimpleBatchBuilder(config);
+// builder.run();
+//
+// SimpleIncrementalBuilder builder1 = new SimpleIncrementalBuilder(config);
+// builder1.run();
+// }
+}
+
diff --git a/org.aspectj.ajdt.core/testsrc/org/aspectj/ajdt/internal/compiler/batch/IncrementalCase.java b/org.aspectj.ajdt.core/testsrc/org/aspectj/ajdt/internal/compiler/batch/IncrementalCase.java
new file mode 100644
index 000000000..e4f645f3a
--- /dev/null
+++ b/org.aspectj.ajdt.core/testsrc/org/aspectj/ajdt/internal/compiler/batch/IncrementalCase.java
@@ -0,0 +1,485 @@
+/* *******************************************************************
+ * Copyright (c) 1999-2001 Xerox Corporation,
+ * 2002 Palo Alto Research Center, Incorporated (PARC).
+ * All rights reserved.
+ * This program and the accompanying materials are made available
+ * under the terms of the Common Public License v1.0
+ * which accompanies this distribution and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * Xerox/PARC initial implementation
+ * ******************************************************************/
+
+package org.aspectj.ajdt.internal.compiler.batch;
+
+import org.aspectj.bridge.ICommand;
+import org.aspectj.bridge.IMessage;
+import org.aspectj.bridge.IMessageHandler;
+import org.aspectj.bridge.IMessageHolder;
+import org.aspectj.bridge.ISourceLocation;
+import org.aspectj.bridge.Message;
+import org.aspectj.bridge.MessageHandler;
+import org.aspectj.bridge.ReflectionFactory;
+import org.aspectj.util.FileUtil;
+import org.aspectj.util.LangUtil;
+
+import java.io.File;
+import java.io.FileFilter;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.BitSet;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Properties;
+
+/**
+ * Mostly stateless incremental test case.
+ * Subclass to use from junit.
+ */
+public class IncrementalCase { // XXX NOT bound to junit - bridge tests?
+ public static final String[] RA_String = new String[0]; // XXX
+ boolean verbose = true;
+ boolean ignoreWarnings = false;
+
+ public static void main(String[] args) throws IOException {
+ IncrementalCase me = new IncrementalCase();
+ MessageHandler h = new MessageHandler();
+ boolean result;
+ StringBuffer sb = new StringBuffer();
+ for (int i = 0; i < args.length; i++) {
+ sb.append("\n###### results for " + args[i]);
+ sb.append("\n" + me.run(new File(args[i]), h) + ": " + h);
+ }
+ System.err.flush();
+ System.out.flush();
+ System.err.println(sb.toString());
+ }
+
+ /**
+ * Run an incremental compile case.
+ * For each i=1..9, copy files srcDir/*{i=1..9}0.java
+ * to the sandbox and compile.
+ * This only expects the changed files to be recompiled, but
+ * it also calls verifyCompile(..);
+ * @param handler all non-functional feedback here.
+ * Exceptions are logged as ABORT messages
+ */
+ public boolean run(File srcBase, IMessageHandler handler)
+ throws IOException {
+ final String cname = ReflectionFactory.ECLIPSE;
+
+ File targetBase =
+ makeDir(getSandboxDir(), "IncrementalCaseSandbox", handler);
+ if (null == targetBase) {
+ return false;
+ }
+ File targetSrc = makeDir(targetBase, "src", handler);
+ if (null == targetSrc) {
+ return false;
+ }
+ File targetClasses = makeDir(targetBase, "classes", handler);
+ if (null == targetClasses) {
+ return false;
+ }
+ final ArrayList files = new ArrayList();
+ final FileFilter collector = new FileFilter() {
+ public boolean accept(File file) {
+ return files.add(file);
+ }
+ };
+ final ICommand compiler =
+ ReflectionFactory.makeCommand(cname, handler);
+
+ ArrayList recompiled = null;
+ boolean result = true;
+
+ final String toSuffix = ".java";
+ final String canonicalFrom = srcBase.getCanonicalPath();
+ final Definition[] defs = getDefinitions(srcBase);
+ if ((null == defs) || (defs.length < 9)) {
+ throw new Error("did not get definitions");
+ }
+ MessageHandler compilerMessages = new MessageHandler();
+ StringBuffer commandLine = new StringBuffer();
+ for (int i = 1; result && (i < 10); i++) {
+ String fromSuffix = "." + i + "0.java";
+ // copy files, collecting as we go...
+ files.clear();
+ FileUtil.copyDir(
+ srcBase,
+ targetSrc,
+ fromSuffix,
+ toSuffix,
+ collector);
+ if (0 == files.size()) { // XXX detect incomplete?
+ break;
+ }
+ List safeFiles = Collections.unmodifiableList(files);
+ log("Compiling ", safeFiles, handler);
+ if (1 == i) {
+ ArrayList argList = new ArrayList();
+ argList.addAll(getBaseArgs(targetSrc, targetClasses));
+ File[] fra = (File[]) safeFiles.toArray(new File[0]);
+ // sigh
+ argList.addAll(
+ Arrays.asList(FileUtil.getAbsolutePaths(fra)));
+ String[] args = (String[]) argList.toArray(new String[0]);
+ commandLine.append(""+argList);
+ result = compiler.runCommand(args, compilerMessages);
+ } else {
+ if (null == recompiled) {
+ recompiled = new ArrayList();
+ } else {
+ recompiled.clear();
+ }
+ compilerMessages.init();
+ commandLine.append("["+i+": " + recompiled + "] ");
+ result =
+ compiler.repeatCommand(compilerMessages);
+ }
+ result =
+ verifyCompile(
+ i,
+ result,
+ srcBase,
+ targetSrc,
+ targetClasses,
+ defs[i - 1],
+ compilerMessages,
+ commandLine,
+ handler);
+ }
+ return result;
+ }
+
+ // -------------------------------------- test case verification
+ /**
+ * Verify that this incremental compile step worked.
+ * @param recompiled the List of Files the compiler recompiled - null the first pass
+ * @param files the (unmodifiable) List of File passed as sources to the compiler
+ * @param recompiled the List sink for the Files actually recompiled
+ */
+ // XXX argh no parent/child relationship in this world...
+ protected boolean verifyCompile(
+ int iteration,
+ boolean result,
+ File srcDir,
+ File sandboxSrcDir,
+ File sandboxClassesDir,
+ Definition def,
+ IMessageHolder compilerMessages,
+ StringBuffer commandLine,
+ IMessageHandler handler) {
+ log("verifyCompile - iteration ", new Integer(iteration), handler);
+ log("verifyCompile - def ", def, handler);
+ log("verifyCompile - command ", commandLine.toString(), handler);
+ log("verifyCompile - messages ", compilerMessages, handler);
+ StringBuffer failures = new StringBuffer();
+ if (def.expectFail == result) {
+ failures.append("iteration " + iteration +
+ " expected to " + (def.expectFail ? "fail\n" : "pass"));
+ }
+ if (0 < failures.length()) {
+ fail(handler,
+ "\nFailures in iteration " + iteration
+ + "\n Command: " + commandLine
+ + "\nMessages: " + compilerMessages
+ + "\n Def: " + def
+ + "\nFailures: " + failures);
+ return false;
+ }
+ IMessage[] messages = compilerMessages.getMessages(IMessage.ERROR, IMessageHolder.EQUAL);
+ String[] expected =
+ (null != def.errors ? def.errors : def.eclipseErrors);
+ if (haveAll("errors", expected, messages, handler)) {
+ if (!ignoreWarnings) {
+ messages = compilerMessages.getMessages(IMessage.WARNING, IMessageHolder.EQUAL);
+ expected =
+ (null != def.warnings
+ ? def.warnings
+ : def.eclipseWarnings);
+ if (!haveAll("warnings", expected, messages, handler)) {
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+
+ // -------------------------------------- test case setup
+ /**
+ * Get the sandbox (parent) directory.
+ * This implementation uses the temporary directory
+ */
+ protected File getSandboxDir() throws IOException { // XXX util
+ File tempFile = File.createTempFile("IncrementalCase", ".txt");
+ File tempDir = tempFile.getParentFile();
+ tempFile.delete();
+ return tempDir;
+ }
+
+ //XXX hack
+ public File outputDir;
+
+ /** @param srcDir ignored for now */
+ protected List getBaseArgs(File srcDir, File classesDir) {
+ outputDir = classesDir;
+ String[] input =
+ new String[] {
+ "-verbose",
+// "-classpath",
+// System.getProperty("sun.boot.class.path"),
+ "-d",
+ classesDir.getAbsolutePath()};
+ return Collections.unmodifiableList(
+ new ArrayList(Arrays.asList(input)));
+ }
+
+ protected File makeDir(
+ File parent,
+ String name,
+ IMessageHandler handler) { // XXX util
+ File result = new File(parent, name);
+ if (!result.exists()) {
+ result.mkdirs();
+ if (!result.exists()) {
+ fail(handler, "unable to create " + result);
+ return null;
+ }
+ }
+ return result;
+ }
+
+ // -------------------------------------- test case verification
+
+
+ List normalizeFilenames(String[] ra) { // XXX util
+ ArrayList result = new ArrayList();
+ if (null != ra) {
+ for (int i = 0; i < ra.length; i++) {
+ result.add(normalizeFilename(ra[i]));
+ }
+ if (1 < ra.length) {
+ Collections.sort(result);
+ }
+ }
+ return result;
+ }
+
+ /** @param list the List of File */
+ List normalizeFilenames(List list) { // XXX util
+ ArrayList result = new ArrayList();
+ for (Iterator iter = list.iterator(); iter.hasNext();) {
+ result.add(normalizeFilename(((File) iter.next()).getPath()));
+ }
+ Collections.sort(result);
+ return result;
+ }
+
+ String normalizeFilename(String s) { // XXX error-prone
+ final String suffix = ".java";
+ int loc = s.lastIndexOf(suffix);
+ if (-1 == loc) {
+ return s; // punt
+ }
+ s = s.substring(0, loc + suffix.length()).replace('\\', '/');
+ loc = s.lastIndexOf("/");
+ return (-1 == loc ? s : s.substring(loc+1));
+ }
+
+
+ /** XXX duplicate message checking */
+ boolean haveAll(
+ String label,
+ String[] expected,
+ IMessage[] messages,
+ IMessageHandler handler) {
+ if (null == expected) {
+ expected = new String[0];
+ }
+ boolean result = true;
+ final int[] exp = new int[expected.length];
+ StringBuffer sb = new StringBuffer();
+ sb.append("[");
+ for (int i = 0; i < exp.length; i++) {
+ String s = expected[i];
+ int loc = s.lastIndexOf(":");
+ if (-1 != loc)
+ s = s.substring(loc + 1);
+ try {
+ exp[i] = Integer.valueOf(s).intValue();
+ sb.append(exp[i] + ((i < (exp.length - 1)) ? ", " : ""));
+ } catch (NumberFormatException e) {
+ info(handler, "bad " + label + ":" + expected[i]);
+ // XXX worse than info...
+ sb.append("bad" + ((i < (exp.length - 1)) ? ", " : "]"));
+ }
+ }
+ sb.append("]");
+ final String context =
+ label
+ + "\n in context haveAll expected="
+ + Arrays.asList(expected)
+ + " exp="
+ + sb
+ + " actual="
+ + Arrays.asList(messages);
+ info(handler, context);
+
+ BitSet foundSet = new BitSet(10);
+ for (int i = 0; i < exp.length; i++) {
+ final int expLine = exp[i];
+ boolean found = false;
+ for (int j = 0; !found && (j < messages.length); j++) {
+ ISourceLocation sl = messages[j].getISourceLocation();
+ found = ((null != sl) && (expLine == sl.getLine()));
+ if (found) {
+ info(handler, "found " + label + " for: " + exp[i]);
+ if (foundSet.get(j)) {
+ info(
+ handler,
+ "duplicate " + label + " expected: " + exp[i]);
+ }
+ foundSet.set(j);
+ }
+ }
+ if (!found) {
+ String s =
+ "expected "
+ + label
+ + " not found: "
+ + exp[i]
+ + context;
+ fail(handler, s); // bad short-circuit
+ if (!result) {
+ result = false;
+ }
+ }
+
+ }
+ sb.setLength(0);
+ for (int i = 0; i < messages.length; i++) {
+ if (!foundSet.get(i)) {
+ sb.append(
+ "\n unexpected " + label + " found: " + messages[i]);
+ }
+ }
+ if (0 == sb.length()) {
+ return true;
+ } else {
+ fail(handler, sb.toString() + context);
+ return false;
+ }
+ }
+ // -------------------------------------- messages
+ protected void log(String label, Object o, IMessageHandler handler) {
+ if (verbose) {
+ if (null != handler) {
+ message(IMessage.INFO, label + ": " + o, handler);
+ } else {
+ System.err.println("\nlog: " + label + ": " + o);
+ }
+ }
+ }
+ protected void info(IMessageHandler handler, String mssg) {
+ message(IMessage.INFO, mssg, handler);
+ }
+ protected void fail(IMessageHandler handler, String mssg) {
+ message(IMessage.FAIL, mssg, handler);
+ }
+
+ /** this is the only client of the message handler - remplement to do other notification*/
+ protected void message(
+ IMessage.Kind kind,
+ String mssg,
+ IMessageHandler handler) {
+ if (null != handler) {
+ handler.handleMessage(
+ new Message("\n### " + mssg, kind, null, null));
+ }
+ }
+
+ /** @return Definition[9] read from srceBase/Definition.PATH */
+ Definition[] getDefinitions(File srcBase) {
+ File file = new File(srcBase, Definition.PATH);
+ Properties props = new Properties();
+ FileInputStream in = null;
+ try {
+ in = new FileInputStream(file);
+ props.load(in);
+ } catch (IOException e) {
+ e.printStackTrace(System.err);
+ } finally {
+ if (null != in)
+ try {
+ in.close();
+ } catch (IOException e) {
+ }
+ }
+ Definition[] result = new Definition[9];
+ for (int i = 0; i < 9; i++) { // XXX matches run
+ result[i] = new Definition((1+i) + "0", props);
+ }
+ return result;
+ }
+
+ static class Definition {
+ static final String PATH = "expected.txt";
+ boolean expectFail;
+ String prefix;
+ String[] files;
+ String[] recompiled;
+ String[] errors;
+ String[] warnings;
+ String[] eclipseErrors;
+ String[] eclipseWarnings;
+ Definition(String prefix, Properties props) {
+ Enumeration keys = props.keys();
+ this.prefix = prefix;
+ files = get(props, prefix + ".files");
+ recompiled = get(props, prefix + ".recompiled");
+ errors = get(props, prefix + ".errors");
+ warnings = get(props, prefix + ".warnings");
+ eclipseErrors = get(props, prefix + ".eclipse.errors");
+ eclipseWarnings = get(props, prefix + ".eclipse.warnings");
+ expectFail =
+ (((null != errors) && (0 < errors.length))
+ || ((null != eclipseErrors)
+ && (0 < eclipseErrors.length)));
+ }
+ String[] get(Properties props, String key) {
+ String s = props.getProperty(key);
+ if (null != s) {
+ return LangUtil.split(s);
+ }
+ return null;
+ }
+ public String toString() {
+ return "Definition "
+ + " expectFail="
+ + expectFail
+ + " prefix="
+ + prefix
+ + " files="
+ + safe(files)
+ + " recompiled="
+ + safe(recompiled)
+ + " errors="
+ + safe(errors)
+ + " warnings="
+ + safe(warnings)
+ + " eclipseErrors="
+ + safe(eclipseErrors)
+ + " eclipseWarnings="
+ + safe(eclipseWarnings);
+ }
+ String safe(String[] in) {
+ return (null == in ? "" : "" + Arrays.asList(in));
+ }
+ }
+}
diff --git a/org.aspectj.ajdt.core/testsrc/org/aspectj/ajdt/internal/compiler/batch/MultipleCompileTestCase.java b/org.aspectj.ajdt.core/testsrc/org/aspectj/ajdt/internal/compiler/batch/MultipleCompileTestCase.java
new file mode 100644
index 000000000..665cc98e4
--- /dev/null
+++ b/org.aspectj.ajdt.core/testsrc/org/aspectj/ajdt/internal/compiler/batch/MultipleCompileTestCase.java
@@ -0,0 +1,35 @@
+/* *******************************************************************
+ * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC).
+ * All rights reserved.
+ * This program and the accompanying materials are made available
+ * under the terms of the Common Public License v1.0
+ * which accompanies this distribution and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * Xerox/PARC initial implementation
+ * ******************************************************************/
+
+package org.aspectj.ajdt.internal.compiler.batch;
+
+import java.io.*;
+
+import org.aspectj.weaver.bcel.*;
+
+import junit.framework.*;
+
+public class MultipleCompileTestCase extends CommandTestCase {
+
+ /**
+ * Constructor for WorkingCommandTestCase.
+ * @param name
+ */
+ public MultipleCompileTestCase(String name) {
+ super(name);
+ }
+
+ public void testA1() throws IOException, InterruptedException {
+ checkMultipleCompile("src1/Hello.java");
+ }
+}
+
diff --git a/org.aspectj.ajdt.core/testsrc/org/aspectj/ajdt/internal/compiler/batch/VerifyWeaveTestCase.java b/org.aspectj.ajdt.core/testsrc/org/aspectj/ajdt/internal/compiler/batch/VerifyWeaveTestCase.java
new file mode 100644
index 000000000..0a7471261
--- /dev/null
+++ b/org.aspectj.ajdt.core/testsrc/org/aspectj/ajdt/internal/compiler/batch/VerifyWeaveTestCase.java
@@ -0,0 +1,114 @@
+/* *******************************************************************
+ * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC).
+ * All rights reserved.
+ * This program and the accompanying materials are made available
+ * under the terms of the Common Public License v1.0
+ * which accompanies this distribution and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * Xerox/PARC initial implementation
+ * ******************************************************************/
+
+package org.aspectj.ajdt.internal.compiler.batch;
+class Ignore {}
+//import java.io.*;
+//import java.util.*;
+//
+//import junit.framework.*;
+//
+////import org.apache.bcel.classfile.*;
+//import org.aspectj.ajdt.ajc.*;
+////import org.aspectj.weaver.bcel.*;
+//import org.aspectj.bridge.*;
+//import org.aspectj.testing.util.TestUtil;
+//import org.aspectj.util.*;
+
+//public class VerifyWeaveTestCase extends WeaveTestCase {
+// {
+// regenerate = false;
+// runTests = true;
+// }
+//
+// static final String outDirName = "out";
+// static final String srcDir = "testdata" + File.separator + "src1"+ File.separator;
+//
+// public VerifyWeaveTestCase(String name) {
+// super(name);
+// }
+//
+// public void testCompile() throws IOException {
+// buildTest("A", "Hello", outDirName);
+// }
+//
+//
+// public boolean doCompile(String fileToCompile, String specifiedOutDir) {
+// List args = new ArrayList();
+// if (specifiedOutDir != null) {
+// args.add("-d");
+// args.add(specifiedOutDir);
+// }
+// args.add("-classpath");
+// args.add("../runtime/bin");
+// args.add(fileToCompile);
+//
+//
+// ICommand command = new AjdtCommand();
+// MessageHandler myHandler = new MessageHandler();
+// command.runCommand((String[])args.toArray(new String[0]), myHandler);
+// IMessage[] info = myHandler.getMessages(IMessage.INFO, IMessageHolder.EQUAL);
+//// System.out.println("info messages: " + Arrays.asList(info));
+//// System.out.println("compiled: " + fileToCompile);
+//// System.out.println("errors: " + Arrays.asList(myHandler.getErrors()));
+//// System.out.println("warnings: " + Arrays.asList(myHandler.getWarnings()));
+// return true;
+// }
+//
+// public void testBuildOutputDir() throws IOException {
+// FileUtil.deleteContents(new File(outDirName));
+//
+// doCompile(srcDir + "A.java", outDirName);
+// assertTrue("default package, output dir specified",
+// new File(outDirName + File.separator + "A.class").exists());
+//
+// File testFile = new File(srcDir + "A.class");
+// //XXX These test for javac compatible behavior with output dirs
+//// testFile.delete();
+//// doCompile(srcDir + "A.java", null);
+//// assertTrue("default package, no output dir specified",
+//// testFile.exists());
+////
+//// doCompile(srcDir + "Ap.java", null);
+//// assertTrue("package named, no dir specified",
+//// new File(srcDir + "Ap.class").exists());
+//
+// doCompile(srcDir + "Ap.java", outDirName);
+// File checkFile =
+// new File(outDirName + File.separator + "src1" + File.separator + "Ap.class");
+// assertTrue("package named, dir specified: " + checkFile.getAbsolutePath(),
+// checkFile.exists());
+//
+// }
+//
+// public void buildTest(String name, String outName, String specifiedOutDir) throws IOException {
+// String classDir = "bin";
+//
+// doCompile(srcDir + name + ".java", specifiedOutDir);
+//
+// LazyClassGen gen = new LazyClassGen(new BcelObjectType(new ClassParser(outDirName + File.separator + outName +".class").parse()));
+//
+// try {
+// checkClass(gen, outDirName, outName + ".txt");
+// if (runTests) {
+// TestUtil.runMain(outDirName, "A");
+// }
+// } catch (Error e) {
+// gen.print(System.err);
+// throw e;
+// } catch (RuntimeException e) {
+// gen.print(System.err);
+// throw e;
+// }
+// }
+//
+//}
diff --git a/org.aspectj.ajdt.core/testsrc/org/aspectj/ajdt/internal/compiler/batch/WorkingTestMain.java b/org.aspectj.ajdt.core/testsrc/org/aspectj/ajdt/internal/compiler/batch/WorkingTestMain.java
new file mode 100644
index 000000000..d93baa036
--- /dev/null
+++ b/org.aspectj.ajdt.core/testsrc/org/aspectj/ajdt/internal/compiler/batch/WorkingTestMain.java
@@ -0,0 +1,131 @@
+/* *******************************************************************
+ * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC).
+ * All rights reserved.
+ * This program and the accompanying materials are made available
+ * under the terms of the Common Public License v1.0
+ * which accompanies this distribution and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * Xerox/PARC initial implementation
+ * ******************************************************************/
+
+package org.aspectj.ajdt.internal.compiler.batch;
+
+import java.io.IOException;
+import java.util.*;
+import java.util.List;
+
+import org.aspectj.testing.util.TestUtil;
+
+public class WorkingTestMain {
+
+ public static void main(String[] args1) throws IOException {
+ //testExamples();
+ testOne();
+ }
+
+ public static void testOne() throws IOException {
+ //CommandTestCase.checkCompile("src1/Parents.java", CommandTestCase.NO_ERRORS);
+
+ //CommandTestCase.checkCompile("../../tests/new/ArgsInCflow2.java", CommandTestCase.NO_ERRORS);
+
+ //CommandTestCase.checkCompile("src1/ParentsFail.java", CommandTestCase.NO_ERRORS);
+
+ List args = new ArrayList();
+ args.add("-verbose");
+
+ args.add("-d");
+ args.add("out");
+
+ args.add("-classpath");
+ args.add("../runtime/bin;../lib/junit/junit.jar;../testing-client/bin");
+ //args.add("../runtime/bin;../lib/junit/junit.jar");
+
+// args.add("-injars");
+// args.add("testdata/testclasses.jar");
+
+ //args.add("-aspectpath");
+ //args.add("../bcweaver/testdata/megatrace.jar");
+
+ //args.add("testdata/src1/AroundA1.java");
+ args.add("../tests/new/StrictFPAdvice.java");
+ //args.add("-Xlint:error");
+ //args.add("testdata/src1/InterType.java");
+ //args.add("@" + examplesDir + "tjp/files.lst");
+
+
+ CommandTestCase.runCompiler(args, CommandTestCase.NO_ERRORS);
+ //CommandTestCase.runCompiler(args, new int[] {11, 14, 18, 32, 43});
+
+ CommandTestCase.printGenerated("../out", "StrictFPAdvice");
+ CommandTestCase.printGenerated("../out", "A");
+
+ //TestUtil.runMain("out;../bcweaver/testdata/megatrace.jar", "Privileged");
+ TestUtil.runMain("out;../lib/test/testing-client.jar", "StrictFPAdvice");
+ }
+
+ private static String examplesDir = "c:/aspectj/examples/";
+ private static void example(String[] argfiles, String[] classes) {
+ List args = new ArrayList();
+ args.add("-verbose");
+
+ args.add("-d");
+ args.add("out");
+
+ args.add("-classpath");
+ args.add("../runtime/bin");
+
+ for (int i=0; i < argfiles.length; i++) {
+ args.add("@" + examplesDir + argfiles[i]);
+ }
+
+ CommandTestCase.runCompiler(args, CommandTestCase.NO_ERRORS);
+ for (int i=0; i < classes.length; i++) {
+ TestUtil.runMain("out", classes[i]);
+ }
+ }
+
+
+ public static void testExamples() throws IOException {
+// example(new String[] {"observer/files.lst"},
+// new String[] {"observer.Demo"});
+
+// example(new String[] {"tjp/files.lst"},
+// new String[] {"tjp.Demo"});
+
+ example(new String[] {"telecom/timing.lst"},
+ new String[] {"telecom.TimingSimulation"});
+
+ example(new String[] {"telecom/billing.lst"},
+ new String[] {"telecom.BillingSimulation"});
+
+ example(new String[] {"tracing/tracev1.lst"},
+ new String[] {"tracing.version1.TraceMyClasses"});
+
+ example(new String[] {"tracing/tracev2.lst"},
+ new String[] {"tracing.version2.TraceMyClasses"});
+
+ example(new String[] {"tracing/tracev3.lst"},
+ new String[] {"tracing.version3.TraceMyClasses"});
+
+
+ example(new String[] {"introduction/files.lst"},
+ new String[] {"introduction.HashablePoint", "introduction.ComparablePoint"});
+
+
+
+
+ example(new String[] {"bean/files.lst"},
+ new String[] {"bean.Demo"});
+
+ example(new String[] {"spacewar/demo.lst"},
+ new String[] {});
+
+ example(new String[] {"spacewar/debug.lst"},
+ new String[] {});
+
+
+ }
+
+}
diff --git a/org.aspectj.ajdt.core/testsrc/org/aspectj/ajdt/internal/core/builder/AjBuildManagerTest.java b/org.aspectj.ajdt.core/testsrc/org/aspectj/ajdt/internal/core/builder/AjBuildManagerTest.java
new file mode 100644
index 000000000..4b98bba37
--- /dev/null
+++ b/org.aspectj.ajdt.core/testsrc/org/aspectj/ajdt/internal/core/builder/AjBuildManagerTest.java
@@ -0,0 +1,366 @@
+/* *******************************************************************
+ * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC).
+ * All rights reserved.
+ * This program and the accompanying materials are made available
+ * under the terms of the Common Public License v1.0
+ * which accompanies this distribution and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * Xerox/PARC initial implementation
+ * ******************************************************************/
+
+package org.aspectj.ajdt.internal.core.builder;
+
+import java.io.*;
+import java.util.*;
+
+import junit.framework.TestCase;
+import org.aspectj.ajdt.ajc.BuildArgParser;
+import org.aspectj.asm.*;
+import org.aspectj.asm.StructureModelManager;
+import org.aspectj.bridge.IMessage;
+import org.aspectj.bridge.MessageHandler;
+import org.aspectj.bridge.MessageWriter;
+import org.aspectj.testing.util.TestUtil;
+import org.aspectj.util.*;
+import org.aspectj.workbench.resources.FilesystemFolder;
+import org.eclipse.core.internal.events.ResourceDelta;
+import org.eclipse.core.resources.*;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.*;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.jdt.internal.core.builder.*;
+import org.eclipse.jdt.internal.core.builder.SimpleLookupTable;
+
+public class AjBuildManagerTest extends TestCase {
+
+ private StreamPrintWriter outputWriter = new StreamPrintWriter(new PrintWriter(System.out));
+ private MessageWriter messageWriter = new MessageWriter(outputWriter, false);
+ public static File source1 = new File("testdata/src1/A.java");
+ public static File source2 = new File("testdata/src1/Hello.java");
+ public static File source3 = new File("testdata/src1/X.java");
+
+ public AjBuildManagerTest(String name) {
+ super(name);
+ }
+
+ public void testSimpleStructure() throws IOException, CoreException {
+
+ AjBuildManager manager = new AjBuildManager(messageWriter);
+ BuildArgParser parser = new BuildArgParser();
+ String javaClassPath = System.getProperty("java.class.path");
+ AjBuildConfig buildConfig =
+ parser.genBuildConfig(new String[] {
+ "-d", "out",
+ "-classpath",
+ javaClassPath,
+ "testdata/src1/A.java",
+// "testdata/src1/Hello.java",
+ }, messageWriter);
+ String err = parser.getOtherMessages(true);
+ assertTrue(err, null == err);
+ manager.setStructureModel(StructureModelManager.INSTANCE.getStructureModel());
+ MessageHandler handler = new MessageHandler();
+ manager.batchBuild(buildConfig, handler);
+ assertEquals(0, handler.numMessages(IMessage.WARNING, true));
+// System.out.println(
+// ">> model: \n" +
+// StructureModelManager.INSTANCE.getStructureModel().getRoot().toLongString()
+// );
+//
+// System.out.println(
+// ">> children: \n" +
+// ((StructureNode)StructureModelManager.INSTANCE.getStructureModel().getRoot().getChildren().get(0)).getChildren()
+// );
+ }
+
+
+
+
+ //XXX add test for resource deltas
+
+ public void testUpdateBuildConfig() {
+ final File FILE_1 = new File("testdata/testclasses/Temp1.java");
+ final File FILE_2 = new File("testdata/testclasses/Temp2.java");
+ final File FILE_3 = new File("testdata/testclasses/Temp3.java");
+ List files = new ArrayList();
+ files.add(FILE_1);
+ files.add(FILE_2);
+
+ AjBuildManager manager = new AjBuildManager(messageWriter);
+ AjBuildConfig buildConfig = new AjBuildConfig();
+ manager.buildConfig = buildConfig;
+ buildConfig.setFiles(files);
+
+ manager.updateBuildConfig(buildConfig);
+ assertTrue("no change", manager.deletedFiles.isEmpty());
+
+ AjBuildConfig newConfig = new AjBuildConfig();
+ newConfig.getFiles().add(FILE_1);
+ newConfig.getFiles().add(FILE_2);
+ newConfig.getFiles().add(FILE_3);
+ manager.updateBuildConfig(newConfig);
+ assertTrue("added file", manager.deletedFiles.isEmpty());
+ assertTrue(manager.addedFiles.size() == 1);
+ assertTrue(manager.addedFiles.contains(FILE_3));
+
+ newConfig = new AjBuildConfig();
+ newConfig.getFiles().add(FILE_3);
+ manager.updateBuildConfig(newConfig);
+ assertTrue("deleted 2 files", manager.addedFiles.isEmpty());
+ assertTrue(manager.deletedFiles.size() == 2);
+ assertTrue(manager.deletedFiles.contains(FILE_1));
+
+ newConfig = new AjBuildConfig();
+ newConfig.getFiles().add(FILE_2);
+ manager.updateBuildConfig(newConfig);
+ assertTrue("added file", manager.addedFiles.size() == 1);
+ assertTrue("deleted file", manager.deletedFiles.size() == 1);
+ assertTrue(manager.deletedFiles.size() == 1);
+ assertTrue(manager.addedFiles.contains(FILE_2));
+ assertTrue(manager.deletedFiles.contains(FILE_3));
+ }
+
+ /**
+ * Pretends that the files 'have been' modified in the future and waits.
+ * Tests:
+ * 1) no change,
+ * 2) added file,
+ * 3) removed file
+ *
+ * XXX should just test modified
+ */
+ public void testGetModifiedFiles() throws IOException, InterruptedException {
+ final File TEMP_1 = new File("testdata/testclasses/TempChanged.java");
+ final File EXISTS_2 = new File("testdata/testclasses/p1/Foo.java");
+ final File NEW = new File("testdata/testclasses/TempNew.java");
+ NEW.delete();
+ touch(TEMP_1, false);
+ List files = new ArrayList();
+ files.add(TEMP_1);
+ files.add(EXISTS_2);
+
+ assertTrue("input files", TEMP_1.exists() && EXISTS_2.exists());
+ assertTrue("new file", !NEW.exists());
+
+ Thread.sleep(100);
+ long lastBuildTime = System.currentTimeMillis();
+
+ AjBuildManager manager = new AjBuildManager(messageWriter);
+ manager.buildConfig = new AjBuildConfig();
+ manager.buildConfig.setFiles(files);
+ Collection changedFiles = manager.getModifiedFiles(lastBuildTime);
+ assertTrue("nothing changed: " + changedFiles, changedFiles.isEmpty());
+
+ lastBuildTime = System.currentTimeMillis();
+ Thread.sleep(100);
+
+ touch(NEW, false);
+
+ //NEW.createNewFile();
+ files.add(NEW);
+ changedFiles = manager.getModifiedFiles(lastBuildTime);
+ assertTrue("new file: " + changedFiles, changedFiles.contains(NEW));
+
+ lastBuildTime = System.currentTimeMillis();
+ Thread.sleep(100);
+
+ files.remove(NEW);
+ changedFiles = manager.getModifiedFiles(lastBuildTime);
+ assertTrue("nothing changed", changedFiles.isEmpty());
+
+ lastBuildTime = System.currentTimeMillis();
+ Thread.sleep(100);
+
+ touch(TEMP_1, true);
+ changedFiles = manager.getModifiedFiles(lastBuildTime);
+ assertTrue("touched file: " + changedFiles, changedFiles.contains(TEMP_1));
+
+ lastBuildTime = System.currentTimeMillis();
+ Thread.sleep(100);
+
+ files.remove(NEW);
+ changedFiles = manager.getModifiedFiles(lastBuildTime);
+ assertTrue("nothing changed", changedFiles.isEmpty());
+
+ TEMP_1.delete();
+ NEW.delete();
+ }
+
+ public void testMakeDeltas() throws IOException, InterruptedException {
+ AjBuildManager manager = new AjBuildManager(messageWriter);
+ manager.buildConfig = new AjBuildConfig();
+ List sourceRoots = new ArrayList();
+ sourceRoots.add(new File("out"));
+ manager.buildConfig.setSourceRoots(sourceRoots);
+ assertTrue(manager.testInit(messageWriter));
+ List modified = Arrays.asList(new File[] { new File("A.java"), new File("B.java") });
+ List deleted = Arrays.asList(new File[] { new File("X.java") });
+ SimpleLookupTable deltas = new SimpleLookupTable();
+ manager.makeDeltas(
+ deltas,
+ modified,
+ deleted,
+ ((File)manager.buildConfig.getSourceRoots().get(0)).getPath());
+
+ ResourceDelta d = (ResourceDelta)deltas.get(manager.getJavaBuilder().currentProject);
+ assertNotNull(d);
+
+ assertEquals(d.getAffectedChildren().length, 3);
+ //XXX do more testing of children
+ }
+
+ // XXX should this be working??
+ public void testDeleteRealFiles() throws CoreException, IOException {
+ AjBuildManager manager = new AjBuildManager(messageWriter);
+ manager.buildConfig = new AjBuildConfig();
+ List sourceRoots = new ArrayList();
+ sourceRoots.add(new File("testdata/src1"));
+ manager.buildConfig.setSourceRoots(sourceRoots);
+ manager.buildConfig.setOutputDir(new File("out"));
+ assertTrue(manager.testInit(messageWriter));
+
+ File realClassFile = new File("out/X.class");
+ touch(realClassFile, false);
+
+ assertTrue(realClassFile.exists());
+
+ IFile classfile = manager.classFileCache.getFile(new Path("X.class"));
+ classfile.create(FileUtil.getStreamFromZip("testdata/testclasses.jar", "Hello.class"), true, null);
+ assertTrue(classfile.exists());
+
+ manager.addAspectClassFilesToWeaver();
+
+ classfile.delete(true, false, null);
+ assertTrue(realClassFile.exists());
+
+ manager.addAspectClassFilesToWeaver();
+
+ assertTrue(!realClassFile.exists());
+
+ }
+
+ public void testIncrementalCompilerCall() throws IOException, InterruptedException, CoreException {
+ AjBuildManager manager = new AjBuildManager(messageWriter);
+
+ manager.buildConfig = new AjBuildConfig();
+ List roots = new ArrayList();
+ roots.add(new File("testdata/src1"));
+ manager.testInit(messageWriter);
+ manager.buildConfig.setSourceRoots(roots);
+ assertTrue(manager.testInit(messageWriter));
+ List modified = Arrays.asList(new File[] { source1, source2 });
+ List deleted = Arrays.asList(new File[] { source3 });
+ SimpleLookupTable deltas = new SimpleLookupTable();
+ manager.makeDeltas(
+ deltas,
+ modified,
+ deleted,
+ ((File)manager.buildConfig.getSourceRoots().get(0)).getAbsolutePath());
+
+ JavaBuilder jbuilder = manager.getJavaBuilder();
+ jbuilder.lastState = new State(jbuilder);
+ jbuilder.binaryResources = new SimpleLookupTable();
+
+ AjBuildManager.IncrementalBuilder builder
+ = manager.getIncrementalBuilder(messageWriter); // XXX trap errors
+ TestNotifier testNotifier = new TestNotifier(builder, jbuilder.currentProject);
+ jbuilder.notifier = testNotifier;
+
+ IContainer[] sourceFolders = new IContainer[] {
+ new FilesystemFolder(((File)manager.buildConfig.getSourceRoots().get(0)).getAbsolutePath())
+ };
+ builder.setSourceFolders(sourceFolders);
+ testNotifier.builder = builder;
+
+ IFile classfile = manager.classFileCache.getFile(new Path("X.class"));
+ classfile.create(new ByteArrayInputStream(new byte[] {1,2,3}), true, null);
+
+ assertTrue(classfile.exists());
+
+
+ try {
+ manager.testSetHandler(messageWriter);
+ boolean succeeded = builder.build(deltas);
+ } catch (NonLocalExit nle) {
+ assertEquals(nle.getExitCode(), 0);
+ } finally {
+ manager.testSetHandler(null);
+ }
+
+ assertTrue(!classfile.exists());
+ }
+
+ static class TestNotifier extends BuildNotifier {
+ int state = 0;
+ AjBuildManager.IncrementalBuilder builder;
+
+ public TestNotifier(AjBuildManager.IncrementalBuilder builder, IProject project) {
+ super(null, project);
+ this.builder = builder;
+ }
+
+
+ public void updateProgressDelta(float percentWorked) {
+ switch(state) {
+ case 0:
+ checkInitialConfig();
+ break;
+ case 1:
+ checkBinaryResources();
+ break;
+ case 2:
+ checkAffectedFiles();
+ break;
+ }
+ state += 1;
+ }
+
+ private void checkBinaryResources() {
+ }
+
+
+ private void checkInitialConfig() {
+ Collection files = builder.getLocations();
+ //System.out.println("initial: " + files);
+ }
+
+ private void checkAffectedFiles() {
+ Collection files = builder.getLocations();
+ TestUtil.assertSetEquals(Arrays.asList(new String[] {
+ source1.getAbsolutePath().replace(File.separatorChar, '/'),
+ source2.getAbsolutePath().replace(File.separatorChar, '/') }), files);
+ throw new NonLocalExit(0);
+ }
+ }
+
+ /**
+ * Method touch.
+ * @param NEW
+ * @param b
+ */
+ private void touch(File file, boolean isAppend) throws IOException {
+ FileOutputStream s = new FileOutputStream(file.getAbsolutePath(), isAppend);
+ s.write(new byte[] {1,2,3});
+ s.close();
+ }
+
+
+ /*
+ * jar
+ * directory
+ * source directory
+ * container
+ */
+// public void testMakeClasspathLocations() {
+// List classpath = new ArrayList();
+// classpath.add(
+//
+// AjBuildConfig config = new AjBuildConfig();
+// config.setClasspath()
+// }
+
+// private void testClasspathLocation(String loca
+
+}
diff --git a/org.aspectj.ajdt.core/testsrc/org/aspectj/ajdt/internal/core/builder/AjdtBuilderTests.java b/org.aspectj.ajdt.core/testsrc/org/aspectj/ajdt/internal/core/builder/AjdtBuilderTests.java
new file mode 100644
index 000000000..55b7690f3
--- /dev/null
+++ b/org.aspectj.ajdt.core/testsrc/org/aspectj/ajdt/internal/core/builder/AjdtBuilderTests.java
@@ -0,0 +1,33 @@
+/* *******************************************************************
+ * Copyright (c) 1999-2001 Xerox Corporation,
+ * 2002 Palo Alto Research Center, Incorporated (PARC).
+ * All rights reserved.
+ * This program and the accompanying materials are made available
+ * under the terms of the Common Public License v1.0
+ * which accompanies this distribution and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * Xerox/PARC initial implementation
+ * ******************************************************************/
+
+
+package org.aspectj.ajdt.internal.core.builder;
+
+import junit.framework.*;
+
+public class AjdtBuilderTests extends TestCase {
+
+ public static Test suite() {
+ TestSuite suite = new TestSuite(AjdtBuilderTests.class.getName());
+ //$JUnit-BEGIN$
+ suite.addTestSuite(AjBuildManagerTest.class);
+ suite.addTestSuite(ClassFileCacheTest.class);
+ suite.addTestSuite(ClasspathContainerTestCase.class);
+ //$JUnit-END$
+ return suite;
+ }
+
+ public AjdtBuilderTests(String name) { super(name); }
+
+}
diff --git a/org.aspectj.ajdt.core/testsrc/org/aspectj/ajdt/internal/core/builder/ClassFileCacheTest.java b/org.aspectj.ajdt.core/testsrc/org/aspectj/ajdt/internal/core/builder/ClassFileCacheTest.java
new file mode 100644
index 000000000..1b8c78bfb
--- /dev/null
+++ b/org.aspectj.ajdt.core/testsrc/org/aspectj/ajdt/internal/core/builder/ClassFileCacheTest.java
@@ -0,0 +1,253 @@
+/* *******************************************************************
+ * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC).
+ * All rights reserved.
+ * This program and the accompanying materials are made available
+ * under the terms of the Common Public License v1.0
+ * which accompanies this distribution and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * Xerox/PARC initial implementation
+ * ******************************************************************/
+
+package org.aspectj.ajdt.internal.core.builder;
+
+import java.io.*;
+import java.util.*;
+
+import junit.framework.TestCase;
+
+import org.aspectj.bridge.MessageHandler;
+import org.aspectj.testing.util.TestUtil;
+import org.aspectj.util.*;
+import org.aspectj.workbench.resources.FilesystemFolder;
+import org.eclipse.core.resources.*;
+import org.eclipse.core.runtime.*;
+
+public class ClassFileCacheTest extends TestCase {
+
+ private MessageHandler handler = new MessageHandler();
+
+ public ClassFileCacheTest(String name) {
+ super(name);
+ }
+
+ public void testExists() throws CoreException {
+ ClassFileCache cache = new ClassFileCache(new FilesystemFolder(new Path("out")), handler);
+ IPath folderPath = new Path("tempfolder");
+ IFolder folder = cache.getFolder(folderPath);
+
+ assertTrue("default folder always exists", cache.exists(new Path("")));
+ assertTrue("default folder always exists", cache.getFolder(new Path("")).exists());
+
+
+ assertTrue("" + folder, !cache.exists(folderPath));
+
+ folder.create(true, true, null);
+ assertTrue("created: " + folderPath, cache.exists(folderPath));
+ assertTrue("created: " + folderPath, cache.getFolder(folderPath).exists());
+
+ folder.delete(true, null);
+ assertTrue("deleted: " + folderPath, !cache.exists(folderPath));
+
+ IPath filePath = new Path("tempfolder/TempClass.class");
+ IFile file = cache.getFile(filePath);
+ assertTrue("" + file, !cache.exists(filePath));
+ assertTrue("" + file, !cache.exists(folderPath));
+
+ createFile(cache, "tempfolder/TempClass.class");
+ assertTrue("" + file, cache.exists(filePath));
+ //XXX should be created when children are
+ //XXXassertTrue("" + file, cache.exists(folderPath));
+ }
+
+ public void testFilesAreCached() throws CoreException {
+ ClassFileCache cache = new ClassFileCache(new FilesystemFolder(new Path("out")), handler);
+ IFolder folder = cache.getFolder(new Path("testpath"));
+ IFile file1 = folder.getFile("Foo.class");
+ assertTrue("" + file1.getClass(), file1 instanceof DeferredWriteFile);
+
+ IFile file2 = cache.getFile(new Path("testpath/Foo.class"));
+ assertTrue("" + file2.getClass(), file2 instanceof DeferredWriteFile);
+
+ assertTrue("" + file1 + ", " + file2, file1 == file2);
+
+
+ folder = cache.getFolder(new Path("testpath"));
+ folder = folder.getFolder("p1");
+ assertTrue("" + folder, !folder.exists());
+
+
+ file1 = folder.getFile(new Path("Bar.class"));
+ file2 = cache.getFile(new Path("testpath/p1/Bar.class"));
+
+ assertTrue("" + file1.getClass(), file1 instanceof DeferredWriteFile);
+ assertTrue("" + file2.getClass(), file2 instanceof DeferredWriteFile);
+
+ assertTrue("" + file1 + ", " + file2, file1 == file2);
+
+
+ assertTrue(!cache.exists(new Path("testpath/p1/Bar.class")));
+
+ InputStream source = new ByteArrayInputStream(new byte[] {0,1,2,3,4,5,6,7,8,9});
+ file1.create(source, true, null);
+ assertTrue(cache.exists(new Path("testpath/p1/Bar.class")));
+
+ file1.delete(true, true, null);
+ assertTrue(!cache.exists(new Path("testpath/p1/Bar.class")));
+
+ IResource[] members = cache.members();
+ assertEquals(members.length, 2);
+
+ DeferredWriteFile dwf1 = (DeferredWriteFile) members[0];
+ DeferredWriteFile dwf2 = (DeferredWriteFile) members[1];
+
+ if (dwf1.getName().endsWith("Bar.class")) {
+ DeferredWriteFile tmp = dwf1;
+ dwf1 = dwf2; dwf2 = tmp;
+ }
+
+ assertTrue(!dwf1.exists());
+ assertTrue(!dwf2.exists());
+
+ assertEquals(dwf1.getName(), "Foo.class");
+ assertEquals(dwf2.getName(), "Bar.class");
+ }
+
+ public void testChange() throws CoreException {
+ MessageHandler handler = new MessageHandler();
+ ClassFileCache cache = new ClassFileCache(new FilesystemFolder(new Path("out")), handler);
+ cache.resetIncrementalInfo();
+ String path1 = "testpath/Foo.class";
+ String path2 = "testpath/Bar.class";
+// cache.getFolder(new Path("testpath")).delete(true, false, null);
+ assertTrue(!cache.getFolder(new Path("testpath")).exists());
+
+ createFile(cache, path1);
+ createFile(cache, path2);
+
+ //XXX assertTrue(cache.getFolder(new Path("testpath")).exists());
+
+ checkFileMatch(cache.getAddedOrChanged(),
+ new String[] { "out/" + path1, "out/" + path2 });
+ checkFileMatch(cache.getDeleted(), new String[0] );
+
+ // added
+ cache.resetIncrementalInfo();
+ String path3 = "testpath/Baz.class";
+ createFile(cache, path3);
+ checkFileMatch(cache.getAddedOrChanged(), new String[] { "out/" + path3 });
+ checkFileMatch(cache.getDeleted(), new String[0] );
+
+ // remove
+ cache.resetIncrementalInfo();
+ deleteFile(cache, path3);
+ checkFileMatch(cache.getDeleted(), new String[] { "out/" + path3 });
+ checkFileMatch(cache.getAddedOrChanged(), new String[0] );
+
+ // change
+ cache.resetIncrementalInfo();
+ createFile(cache, path1);
+
+ deleteFile(cache, path2);
+ createFile(cache, path2);
+
+ checkFileMatch(cache.getAddedOrChanged(),
+ new String[] { "out/" + path1, "out/" + path2 });
+ checkFileMatch(cache.getDeleted(), new String[0] );
+ }
+
+ public void testWrite() throws CoreException {
+ MessageHandler handler = new MessageHandler();
+ clearDirectory("out");
+ checkEmpty("out");
+
+ ClassFileCache cache = new ClassFileCache(new FilesystemFolder(new Path("out")), handler);
+ cache.resetIncrementalInfo();
+ String path1 = "testpath/Foo.class";
+ String path2 = "testpath/Bar.class";
+ createFile(cache, path1);
+ createFile(cache, path2);
+
+ checkEmpty("out");
+
+ writeCache(cache);
+
+ checkContents("out", new String[] {"out/" + path1, "out/" + path2});
+
+ deleteFile(cache, path2);
+ checkContents("out", new String[] {"out/" + path1, "out/" + path2});
+ writeCache(cache);
+
+ checkContents("out", new String[] {"out/" + path1});
+ }
+
+ private void writeCache(ClassFileCache cache) throws CoreException {
+ IResource[] members = cache.members();
+ for (int i = 0; i < members.length; i++) {
+ IResource iResource = members[i];
+ DeferredWriteFile file = (DeferredWriteFile) iResource;
+ //System.out.println("about to write: " + file);
+ if (file.exists()) {
+ file.writeWovenBytes(new byte[] { 0, 1, 2,3});
+ } else {
+ file.deleteRealFile();
+ }
+ }
+ }
+
+ private void checkContents(String path, String[] files) {
+ File dir = new File(path);
+ assertTrue(dir.exists());
+ List allFiles = new ArrayList();
+ listRecursively(new File(path), allFiles, "");
+ TestUtil.assertSetEquals(Arrays.asList(files), allFiles);
+ }
+
+ private void listRecursively(File file, List accumulator, String prefix) {
+ if (file.isDirectory()) {
+ if (prefix.length() == 0) prefix = file.getName() + "/";
+ else prefix = prefix + file.getName() + "/";
+ File[] files = file.listFiles();
+ for (int i = 0; i < files.length; i++) {
+ listRecursively(files[i], accumulator, prefix);
+ }
+ } else {
+ accumulator.add(prefix + file.getName());
+ }
+ }
+
+
+
+ private void checkEmpty(String path) {
+ checkContents(path, new String[0]);
+ }
+
+
+ private void clearDirectory(String path) {
+ FileUtil.deleteContents(new File(path));
+ }
+
+
+ private void checkFileMatch(List list, String[] names) {
+ Set found = new HashSet();
+ for (Iterator iter = list.iterator(); iter.hasNext();) {
+ EclipseUnwovenClassFile file = (EclipseUnwovenClassFile) iter.next();
+ found.add(file.getFile().getFullPath().toString());
+ }
+
+ TestUtil.assertSetEquals(Arrays.asList(names), found);
+ }
+
+ private void createFile(ClassFileCache cache, String path) throws CoreException {
+ IFile file = cache.getFile(new Path(path));
+ InputStream source = new ByteArrayInputStream(new byte[] {0,1,2,3,4,5,6,7,8,9});
+ file.create(source, true, null);
+ }
+
+ private void deleteFile(ClassFileCache cache, String path) throws CoreException {
+ IFile file = cache.getFile(new Path(path));
+ file.delete(true, null);
+ }
+
+}
diff --git a/org.aspectj.ajdt.core/testsrc/org/aspectj/ajdt/internal/core/builder/ClasspathContainerTestCase.java b/org.aspectj.ajdt.core/testsrc/org/aspectj/ajdt/internal/core/builder/ClasspathContainerTestCase.java
new file mode 100644
index 000000000..cc06fa901
--- /dev/null
+++ b/org.aspectj.ajdt.core/testsrc/org/aspectj/ajdt/internal/core/builder/ClasspathContainerTestCase.java
@@ -0,0 +1,66 @@
+/* *******************************************************************
+ * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC).
+ * All rights reserved.
+ * This program and the accompanying materials are made available
+ * under the terms of the Common Public License v1.0
+ * which accompanies this distribution and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * Xerox/PARC initial implementation
+ * ******************************************************************/
+
+package org.aspectj.ajdt.internal.core.builder;
+
+import java.io.IOException;
+
+import junit.framework.TestCase;
+
+import org.aspectj.util.FileUtil;
+import org.aspectj.workbench.resources.FilesystemFolder;
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.jdt.internal.compiler.env.NameEnvironmentAnswer;
+import org.eclipse.jdt.internal.core.builder.ClasspathLocation;
+
+public class ClasspathContainerTestCase extends TestCase {
+
+ public ClasspathContainerTestCase(String name) {
+ super(name);
+ }
+
+ // XXX add some inner cases
+ public void testFindClass() throws IOException {
+ FileUtil.extractJar("testdata/testclasses.jar", "out/testclasses");
+
+
+ IContainer container = new FilesystemFolder(new Path("out/testclasses"));
+ ClasspathLocation classpathLocation = new ClasspathContainer(container);
+ // put back in for sanity check
+ //classpathLocation = ClasspathContainer.forBinaryFolder("testdata/testclasses");
+
+ NameEnvironmentAnswer answer = classpathLocation.findClass("Hello.class", "", "Hello.class");
+ assertTrue("" + answer, answer != null);
+
+ NameEnvironmentAnswer answer2 = classpathLocation.findClass("Foo.class", "p1", "p1/Foo.class");
+ assertTrue("" + answer2, answer2 != null);
+
+ NameEnvironmentAnswer answer3 = classpathLocation.findClass("DoesNotExist.class", "", "DoesNotExist.class");
+ assertTrue("" + answer3, answer3 == null);
+
+ NameEnvironmentAnswer answer4 = classpathLocation.findClass("DoesNotExist.class", "p1", "DoesNotExist.class");
+ assertTrue("" + answer4, answer4 == null);
+
+
+ }
+
+ public void testIsPackage() {
+ IContainer container = new FilesystemFolder(new Path("testdata/testclasses"));
+ ClasspathLocation classpathLocation = new ClasspathContainer(container);
+
+ assertTrue("is a package", classpathLocation.isPackage("p1"));
+ assertTrue("is not a package", !classpathLocation.isPackage("mumble"));
+ assertTrue("is not a package", !classpathLocation.isPackage("Hello.class"));
+ }
+
+}
diff --git a/org.aspectj.ajdt.core/testsrc/org/aspectj/workbench/resources/FilesystemFileTest.java b/org.aspectj.ajdt.core/testsrc/org/aspectj/workbench/resources/FilesystemFileTest.java
new file mode 100644
index 000000000..a320cceec
--- /dev/null
+++ b/org.aspectj.ajdt.core/testsrc/org/aspectj/workbench/resources/FilesystemFileTest.java
@@ -0,0 +1,112 @@
+/* *******************************************************************
+ * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC).
+ * All rights reserved.
+ * This program and the accompanying materials are made available
+ * under the terms of the Common Public License v1.0
+ * which accompanies this distribution and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * Xerox/PARC initial implementation
+ * ******************************************************************/
+
+
+package org.aspectj.workbench.resources;
+
+import java.io.*;
+import java.io.FileInputStream;
+
+import junit.framework.TestCase;
+import org.aspectj.util.FileUtil;
+import org.eclipse.core.runtime.*;
+import org.eclipse.core.runtime.IProgressMonitor;
+
+//XXX this *has* to be tested on Linux
+public class FilesystemFileTest extends TestCase {
+
+ private static final String PATH = "testdata" + File.separator + "resources" + File.separator;
+
+ private static final String TEST = PATH + "test.txt";
+ private static final String SOURCE = PATH + "file.txt";
+ private static final String EMPTY = PATH + "empty.txt";
+ private IProgressMonitor monitor = new NullProgressMonitor();
+ private FilesystemFile file;
+ private File javaFile;
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ file = new FilesystemFile(TEST);
+ javaFile = new File(TEST);
+ }
+
+ protected void tearDown() throws Exception {
+ super.tearDown();
+ if (file.exists()) file.delete(true, monitor);
+ }
+
+ public FilesystemFileTest(String name) {
+ super(name);
+ }
+
+ public void testCreateExistsContentsDelete() throws FileNotFoundException, CoreException, InterruptedException, IOException {
+ if (file.exists()) file.delete(true, monitor);
+ assertTrue(!file.exists());
+ FileInputStream fis = new FileInputStream(SOURCE);
+
+ file.create(fis, 0, monitor);
+ fis.close();
+ assertTrue(file.exists());
+
+ String expected = FileUtil.readAsString(new File(SOURCE));
+ String contents = FileUtil.readAsString(file.getContents());
+ assertEquals(expected, contents);
+
+ file.setContents(new FileInputStream(EMPTY), 0, monitor);
+ assertEquals("", FileUtil.readAsString(file.getContents()));
+
+ file.delete(true, monitor);
+ assertTrue(!file.exists());
+ }
+
+ public void testGetFileExtension() {
+ assertEquals(file.getFileExtension(), "txt");
+ }
+
+ public void testGetFullPath() {
+ assertEquals(file.getFullPath().toString(), javaFile.getPath().replace('\\', '/'));
+ }
+
+ public void testGetLocation() {
+ assertEquals(file.getLocation().toString(), javaFile.getAbsolutePath().replace('\\', '/'));
+ }
+
+ public void testGetName() {
+ assertEquals(file.getName(), javaFile.getName());
+ }
+
+ public void testGetModificationStamp() throws IOException, CoreException {
+ FileInputStream fis = new FileInputStream(SOURCE);
+ file.create(fis, 0, monitor);
+ assertEquals(file.getModificationStamp(), javaFile.lastModified());
+ }
+
+ public void testGetParent() {
+ assertEquals(file.getParent().getFullPath().toString(), javaFile.getParentFile().getPath().replace('\\', '/'));
+ }
+
+ public void testReadOnly() throws CoreException, IOException {
+ FileInputStream fis = new FileInputStream(SOURCE);
+ file.create(fis, 0, monitor);
+
+ assertTrue(!file.isReadOnly());
+ file.setReadOnly(true);
+ assertTrue(file.isReadOnly());
+ }
+
+ //XXX not implemented
+ public void testCopy() { }
+
+ //XXX not implemented
+ public void testTouch() { }
+
+}
diff --git a/org.aspectj.ajdt.core/testsrc/org/aspectj/workbench/resources/FilesystemFolderTest.java b/org.aspectj.ajdt.core/testsrc/org/aspectj/workbench/resources/FilesystemFolderTest.java
new file mode 100644
index 000000000..a958808f2
--- /dev/null
+++ b/org.aspectj.ajdt.core/testsrc/org/aspectj/workbench/resources/FilesystemFolderTest.java
@@ -0,0 +1,128 @@
+/* *******************************************************************
+ * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC).
+ * All rights reserved.
+ * This program and the accompanying materials are made available
+ * under the terms of the Common Public License v1.0
+ * which accompanies this distribution and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * Xerox/PARC initial implementation
+ * ******************************************************************/
+
+package org.aspectj.workbench.resources;
+
+import java.io.*;
+import junit.framework.TestCase;
+import org.eclipse.core.resources.*;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.runtime.*;
+import org.eclipse.core.runtime.IProgressMonitor;
+
+public class FilesystemFolderTest extends TestCase {
+
+ private static final String PATH = "testdata" + File.separator + "resources" + File.separator;
+ private static final String DIR = PATH + "dir";
+ private IProgressMonitor monitor = new NullProgressMonitor();
+ private FilesystemFolder dir;
+ private File javaDir;
+
+ public FilesystemFolderTest(String name) {
+ super(name);
+ }
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ dir = new FilesystemFolder(DIR);
+ javaDir = new File(DIR);
+ }
+
+ protected void tearDown() throws Exception {
+ super.tearDown();
+ dir.delete(true, monitor);
+ }
+
+ public void testCreateExistsDelete() throws CoreException {
+ dir.delete(true, monitor);
+ assertTrue(!dir.exists());
+
+ dir.create(true, true, monitor);
+ assertTrue(dir.exists());
+ assertTrue(javaDir.exists());
+
+ dir.delete(true, monitor);
+ assertTrue(!dir.exists());
+ assertTrue(!javaDir.exists());
+ }
+
+ public void testGetFullPath() {
+ assertEquals(dir.getFullPath().toString(), javaDir.getPath().replace('\\', '/'));
+ }
+
+ public void testGetLocation() {
+ assertEquals(dir.getLocation().toString(), javaDir.getAbsolutePath().replace('\\', '/'));
+ }
+
+ public void testGetName() {
+ assertEquals(dir.getName(), javaDir.getName());
+ }
+
+ public void testGetModificationStamp() throws CoreException {
+ dir.create(true, true, monitor);
+ assertEquals(dir.getModificationStamp(), javaDir.lastModified());
+ }
+
+ public void testReadOnly() throws CoreException, IOException {
+ dir.create(true, true, monitor);
+
+ assertTrue(!dir.isReadOnly());
+ assertTrue(javaDir.canWrite());
+ dir.setReadOnly(true);
+ assertTrue(dir.isReadOnly());
+ assertTrue(!javaDir.canWrite());
+ }
+
+ public void testGetParent() {
+ assertEquals(dir.getParent().getFullPath().toString(), javaDir.getParentFile().getPath().replace('\\', '/'));
+ }
+
+ public void testExistsAbsoluteAndRelativeIPath() throws CoreException {
+ final String CHILD_PATH = DIR + File.separator + "child";
+ IPath childIPath = new Path(CHILD_PATH);
+ FilesystemFolder child = new FilesystemFolder(CHILD_PATH);
+
+ child.create(true, true, monitor);
+ assertTrue("relative", dir.exists(childIPath));
+
+ IPath absoluteChildIPath = new Path(new File(CHILD_PATH).getAbsolutePath());
+ assertTrue("absolute", dir.exists(absoluteChildIPath));
+ }
+
+ public void testGetFileIPath() {
+ final String DIRFILE = "dirfile.txt";
+ IFile dirfile = dir.getFile(DIRFILE);
+ assertEquals(
+ dirfile.getLocation().toString(),
+ new File(DIR + File.separator + DIRFILE).getAbsolutePath().replace('\\', '/'));
+ }
+
+ public void testGetFolderIPath() {
+ final String DIRFOLDER = "dirfolder";
+ IFolder dirfile = dir.getFolder(DIRFOLDER);
+ assertEquals(
+ dirfile.getLocation().toString(),
+ new File(DIR + File.separator + DIRFOLDER).getAbsolutePath().replace('\\', '/'));
+ }
+
+ //XXX not implemented
+ public void testCopy() { }
+
+ //XXX not implemented
+ public void testTouch() { }
+
+ //XXX not implemented
+ public void testFindMemberIPath() { }
+
+ //XXX not implemented
+ public void testMembers() { }
+}
diff --git a/org.aspectj.ajdt.core/testsrc/org/aspectj/workbench/resources/WorkspaceResourcesTests.java b/org.aspectj.ajdt.core/testsrc/org/aspectj/workbench/resources/WorkspaceResourcesTests.java
new file mode 100644
index 000000000..bba3f0c01
--- /dev/null
+++ b/org.aspectj.ajdt.core/testsrc/org/aspectj/workbench/resources/WorkspaceResourcesTests.java
@@ -0,0 +1,31 @@
+/* *******************************************************************
+ * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC).
+ * All rights reserved.
+ * This program and the accompanying materials are made available
+ * under the terms of the Common Public License v1.0
+ * which accompanies this distribution and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * Xerox/PARC initial implementation
+ * ******************************************************************/
+
+package org.aspectj.workbench.resources;
+
+import junit.framework.*;
+
+public class WorkspaceResourcesTests {
+
+ public static void main(String[] args) {
+ }
+
+ public static Test suite() {
+ TestSuite suite =
+ new TestSuite("Test for org.aspectj.workbench.resources");
+ //$JUnit-BEGIN$
+ suite.addTest(new TestSuite(FilesystemFileTest.class));
+ suite.addTest(new TestSuite(FilesystemFolderTest.class));
+ //$JUnit-END$
+ return suite;
+ }
+}