Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWalter Harley2006-01-20 01:04:48 +0000
committerWalter Harley2006-01-20 01:04:48 +0000
commit6fea7eafdd413dccff31028f8da1f1ac6859e6fe (patch)
treed21f8a6a1a96c18c4c4706c412bbf5f2a589b773
parentc4c0df5e4aeb7d3e8571312c597020a7d0812327 (diff)
downloadeclipse.jdt.core-6fea7eafdd413dccff31028f8da1f1ac6859e6fe.tar.gz
eclipse.jdt.core-6fea7eafdd413dccff31028f8da1f1ac6859e6fe.tar.xz
eclipse.jdt.core-6fea7eafdd413dccff31028f8da1f1ac6859e6fe.zip
wharley - merge from 3.1.1 to 3.2. Base of merge is v20060120-0034.
-rw-r--r--org.eclipse.jdt.apt.core/.settings/org.eclipse.core.resources.prefs3
-rw-r--r--org.eclipse.jdt.apt.core/scripts/build-sdk-prime.cmd2
-rw-r--r--org.eclipse.jdt.apt.core/scripts/exportplugin.xml4
-rw-r--r--org.eclipse.jdt.apt.core/src/org/eclipse/jdt/apt/core/AptPlugin.java28
-rw-r--r--org.eclipse.jdt.apt.core/src/org/eclipse/jdt/apt/core/Messages.java28
-rw-r--r--org.eclipse.jdt.apt.core/src/org/eclipse/jdt/apt/core/internal/AptProject.java45
-rw-r--r--org.eclipse.jdt.apt.core/src/org/eclipse/jdt/apt/core/internal/declaration/ASTBasedConstructorDeclarationImpl.java38
-rw-r--r--org.eclipse.jdt.apt.core/src/org/eclipse/jdt/apt/core/internal/declaration/ASTBasedExecutableDeclarationImpl.java111
-rw-r--r--org.eclipse.jdt.apt.core/src/org/eclipse/jdt/apt/core/internal/declaration/ASTBasedMethodDeclarationImpl.java77
-rw-r--r--org.eclipse.jdt.apt.core/src/org/eclipse/jdt/apt/core/internal/declaration/ClassDeclarationImpl.java61
-rw-r--r--org.eclipse.jdt.apt.core/src/org/eclipse/jdt/apt/core/internal/declaration/TypeDeclarationImpl.java135
-rw-r--r--org.eclipse.jdt.apt.core/src/org/eclipse/jdt/apt/core/internal/env/BaseProcessorEnv.java124
-rw-r--r--org.eclipse.jdt.apt.core/src/org/eclipse/jdt/apt/core/internal/env/BinaryFileOutputStream.java10
-rw-r--r--org.eclipse.jdt.apt.core/src/org/eclipse/jdt/apt/core/internal/env/ProcessorEnvImpl.java2
-rw-r--r--org.eclipse.jdt.apt.core/src/org/eclipse/jdt/apt/core/internal/generatedfile/ClasspathUtil.java6
-rw-r--r--org.eclipse.jdt.apt.core/src/org/eclipse/jdt/apt/core/internal/generatedfile/GeneratedFileManager.java4
-rw-r--r--org.eclipse.jdt.apt.core/src/org/eclipse/jdt/apt/core/internal/generatedfile/GeneratedResourceChangeListener.java6
-rw-r--r--org.eclipse.jdt.apt.core/src/org/eclipse/jdt/apt/core/internal/generatedfile/GeneratedSourceFolderManager.java592
-rw-r--r--org.eclipse.jdt.apt.core/src/org/eclipse/jdt/apt/core/internal/type/ArrayTypeImpl.java2
-rw-r--r--org.eclipse.jdt.apt.core/src/org/eclipse/jdt/apt/core/internal/util/Factory.java8
-rw-r--r--org.eclipse.jdt.apt.core/src/org/eclipse/jdt/apt/core/internal/util/FileSystemUtil.java35
-rw-r--r--org.eclipse.jdt.apt.core/src/org/eclipse/jdt/apt/core/internal/util/TypesUtil.java6
-rw-r--r--org.eclipse.jdt.apt.core/src/org/eclipse/jdt/apt/core/messages.properties1
-rw-r--r--org.eclipse.jdt.apt.core/src/org/eclipse/jdt/apt/core/util/AptConfig.java63
-rw-r--r--org.eclipse.jdt.apt.tests/plugin.xml3
-rw-r--r--org.eclipse.jdt.apt.tests/src/org/eclipse/jdt/apt/tests/MirrorDeclarationTests.java96
-rw-r--r--org.eclipse.jdt.apt.tests/src/org/eclipse/jdt/apt/tests/annotations/BaseProcessor.java31
-rw-r--r--org.eclipse.jdt.apt.tests/src/org/eclipse/jdt/apt/tests/annotations/mirrortest/ASTBasedMirrorDeclarationProcessorFactory.java122
-rw-r--r--org.eclipse.jdt.apt.ui/scripts/exportplugin.xml2
-rw-r--r--org.eclipse.jdt.apt.ui/src/org/eclipse/jdt/apt/ui/internal/preferences/AptConfigurationBlock.java23
30 files changed, 1076 insertions, 592 deletions
diff --git a/org.eclipse.jdt.apt.core/.settings/org.eclipse.core.resources.prefs b/org.eclipse.jdt.apt.core/.settings/org.eclipse.core.resources.prefs
index e1e45ea8e3..e9ac78be6a 100644
--- a/org.eclipse.jdt.apt.core/.settings/org.eclipse.core.resources.prefs
+++ b/org.eclipse.jdt.apt.core/.settings/org.eclipse.core.resources.prefs
@@ -1,6 +1,5 @@
-#Thu Aug 18 15:38:15 PDT 2005
+#Wed Jan 11 15:27:03 PST 2006
eclipse.preferences.version=1
encoding//src/org/eclipse/jdt/apt/core/build/messages.properties=8859_1
encoding//src/org/eclipse/jdt/apt/core/internal/messages.properties=8859_1
encoding//src/org/eclipse/jdt/apt/core/internal/util/messages.properties=8859_1
-encoding//src/org/eclipse/jdt/apt/core/messages.properties=8859_1
diff --git a/org.eclipse.jdt.apt.core/scripts/build-sdk-prime.cmd b/org.eclipse.jdt.apt.core/scripts/build-sdk-prime.cmd
index 36b4485ef4..ded674b2ca 100644
--- a/org.eclipse.jdt.apt.core/scripts/build-sdk-prime.cmd
+++ b/org.eclipse.jdt.apt.core/scripts/build-sdk-prime.cmd
@@ -43,7 +43,7 @@ if NOT EXIST "%2" (
@set ROOT=%1
@set FULL_SDK_ZIP=%2
-@set APT_VERSION=3.1.1.apt02
+@set APT_VERSION=3.1.1.apt03
@set JDT_VERSION=3.1.1
@set TEMPDIR=\temp\eclipse_sdk_mod
diff --git a/org.eclipse.jdt.apt.core/scripts/exportplugin.xml b/org.eclipse.jdt.apt.core/scripts/exportplugin.xml
index 423d9e01d8..fb1b2e8c38 100644
--- a/org.eclipse.jdt.apt.core/scripts/exportplugin.xml
+++ b/org.eclipse.jdt.apt.core/scripts/exportplugin.xml
@@ -22,7 +22,7 @@
<target name="export plug-in [_1.0.0]">
<antcall target="zz_internal_export">
- <param name="plugin_version" value="3.1.1.apt02"/>
+ <param name="plugin_version" value="3.1.1.apt03"/>
</antcall>
</target>
@@ -45,7 +45,7 @@
<echo message="UPDATE ${plugin}_${plugin_version}.jar" />
<zip zipfile="${plugin-dir}/${plugin}_${plugin_version}.jar">
<fileset dir=".">
- <include name="tools.jar" />
+ <include name="mirrorapi.jar" />
<include name="plugin.xml" />
<include name="plugin.properties" />
<include name="META-INF/**" />
diff --git a/org.eclipse.jdt.apt.core/src/org/eclipse/jdt/apt/core/AptPlugin.java b/org.eclipse.jdt.apt.core/src/org/eclipse/jdt/apt/core/AptPlugin.java
index 4fff1fb633..14af0a5fbe 100644
--- a/org.eclipse.jdt.apt.core/src/org/eclipse/jdt/apt/core/AptPlugin.java
+++ b/org.eclipse.jdt.apt.core/src/org/eclipse/jdt/apt/core/AptPlugin.java
@@ -11,14 +11,11 @@
package org.eclipse.jdt.apt.core;
-import java.io.IOException;
-import java.io.InputStream;
import java.util.Map;
import java.util.WeakHashMap;
import org.eclipse.core.resources.IResourceChangeEvent;
import org.eclipse.core.runtime.IStatus;
-import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.Plugin;
import org.eclipse.core.runtime.Status;
@@ -33,15 +30,12 @@ import org.osgi.framework.BundleContext;
public class AptPlugin extends Plugin {
public static final String PLUGIN_ID = "org.eclipse.jdt.apt.core"; //$NON-NLS-1$
- private static final String TOOLSJARNAME = "./tools.jar"; //$NON-NLS-1$
-
/**
* Status IDs for system log entries. Must be unique per plugin.
*/
public static final int STATUS_EXCEPTION = 1;
public static final int STATUS_NOTOOLSJAR = 2;
public static final int STATUS_CANTLOADPLUGINFACTORY = 3;
- public static final String ERRTXT_NOTOOLSJAR = Messages.AptPlugin_couldNotFindToolsDotJar;
public static final String APT_BATCH_PROCESSOR_PROBLEM_MARKER = PLUGIN_ID + ".marker"; //$NON-NLS-1$
/** Marker ID used for build problem, e.g., missing factory jar */
@@ -62,7 +56,6 @@ public class AptPlugin extends Plugin {
thePlugin = this;
super.start(context);
initDebugTracing();
- checkToolsJar();
AptConfig.initialize();
AnnotationProcessorFactoryLoader.getLoader();
// register resource-changed listener
@@ -73,27 +66,6 @@ public class AptPlugin extends Plugin {
trace("registered resource change listener"); //$NON-NLS-1$
}
- /**
- * Check for the Sun mirror interfaces. If they aren't found,
- * log an error.
- */
- private void checkToolsJar() {
- boolean foundToolsJar = true;
- InputStream is = null;
- try {
- is = thePlugin.openStream(new Path(TOOLSJARNAME));
- }
- catch (IOException e) {
- foundToolsJar = false;
- }
- finally {
- try {if (is != null) is.close();} catch (IOException ioe) {}
- }
- if (!foundToolsJar) {
- log(new Status(IStatus.ERROR, PLUGIN_ID, STATUS_NOTOOLSJAR, ERRTXT_NOTOOLSJAR, null));
- }
- }
-
public void stop(BundleContext context) throws Exception {
super.stop(context);
}
diff --git a/org.eclipse.jdt.apt.core/src/org/eclipse/jdt/apt/core/Messages.java b/org.eclipse.jdt.apt.core/src/org/eclipse/jdt/apt/core/Messages.java
deleted file mode 100644
index f82c96a003..0000000000
--- a/org.eclipse.jdt.apt.core/src/org/eclipse/jdt/apt/core/Messages.java
+++ /dev/null
@@ -1,28 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2005 BEA Systems, Inc.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * jgarms@bea.com - initial API and implementation
- *
- *******************************************************************************/
-package org.eclipse.jdt.apt.core;
-
-import org.eclipse.osgi.util.NLS;
-
-public class Messages extends NLS {
- private static final String BUNDLE_NAME = "org.eclipse.jdt.apt.core.messages"; //$NON-NLS-1$
-
- private Messages() {
- }
-
- static {
- // initialize resource bundle
- NLS.initializeMessages(BUNDLE_NAME, Messages.class);
- }
-
- public static String AptPlugin_couldNotFindToolsDotJar;
-}
diff --git a/org.eclipse.jdt.apt.core/src/org/eclipse/jdt/apt/core/internal/AptProject.java b/org.eclipse.jdt.apt.core/src/org/eclipse/jdt/apt/core/internal/AptProject.java
index 249090f75e..b42b8330af 100644
--- a/org.eclipse.jdt.apt.core/src/org/eclipse/jdt/apt/core/internal/AptProject.java
+++ b/org.eclipse.jdt.apt.core/src/org/eclipse/jdt/apt/core/internal/AptProject.java
@@ -41,46 +41,33 @@ public class AptProject {
}
/**
+ * This method should be called whenever compilation begins, to perform
+ * initialization and verify configuration.
+ */
+ public void compilationStarted() {
+ _gfm.compilationStarted();
+ }
+
+ /**
* This method should be called whenever project preferences are
- * changed by the user. It is safe to call it on every change;
- * irrelevant changes will be efficiently ignored. This may cause
- * the classpath and generated source folder to change, so this
- * should <em>not</em> be called from a resource change listener,
- * preference change listener, or other context where resources
- * may be locked.
+ * changed by the user. This may cause the classpath and generated
+ * source folder to change, so this should <em>not</em> be called
+ * from a context where resources may be locked, e.g., within
+ * certain resource change listeners.
* @param key a preference key such as @see AptPreferenceConstants#APT_ENABLED
* @param oldValue the old value, or null if unknown
* @param newValue the new value, which will be ignored if it is null
*/
- public void handlePreferenceChange(String key, String oldValue, String newValue) {
- if (newValue == null) {
- // Null is used to indicate this preference has
- // been removed, as the project has been deleted.
- // We do nothing.
- return;
- }
- if (newValue.equals(oldValue)) {
- // Nothing has changed
- return;
- }
-
+ public void preferenceChanged(String key) {
if (AptPreferenceConstants.APT_GENSRCDIR.equals(key)) {
- _gsfm.changeFolderName(oldValue, newValue);
+ _gsfm.folderNamePreferenceChanged();
}
else if(AptPreferenceConstants.APT_ENABLED.equals(key) ){
- _gsfm.setEnabled(Boolean.parseBoolean(newValue));
+ _gsfm.enabledPreferenceChanged();
}
}
/**
- * This method should be called whenever compilation begins, to perform
- * initialization and verify configuration.
- */
- public void compilationStarted() {
- _gfm.compilationStarted();
- }
-
- /**
* Invoked whenever a project is cleaned. This will remove any state kept about
* generated files for the given project. If the deleteFiles flag is specified,
* then the contents of the generated source folder will be deleted.
@@ -135,5 +122,5 @@ public class AptProject {
{
_gfm.clearAllMaps();
}
-
+
}
diff --git a/org.eclipse.jdt.apt.core/src/org/eclipse/jdt/apt/core/internal/declaration/ASTBasedConstructorDeclarationImpl.java b/org.eclipse.jdt.apt.core/src/org/eclipse/jdt/apt/core/internal/declaration/ASTBasedConstructorDeclarationImpl.java
new file mode 100644
index 0000000000..e5e3529e31
--- /dev/null
+++ b/org.eclipse.jdt.apt.core/src/org/eclipse/jdt/apt/core/internal/declaration/ASTBasedConstructorDeclarationImpl.java
@@ -0,0 +1,38 @@
+/*******************************************************************************
+ * Copyright (c) 2005 BEA Systems, Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * tyeung@bea.com - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.apt.core.internal.declaration;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.jdt.apt.core.internal.env.BaseProcessorEnv;
+import com.sun.mirror.declaration.ConstructorDeclaration;
+
+import com.sun.mirror.util.DeclarationVisitor;
+
+public class ASTBasedConstructorDeclarationImpl
+ extends ASTBasedExecutableDeclarationImpl
+ implements ConstructorDeclaration{
+
+ public ASTBasedConstructorDeclarationImpl(
+ final org.eclipse.jdt.core.dom.BodyDeclaration astNode,
+ final IFile file,
+ final BaseProcessorEnv env)
+ {
+ super(astNode, file, env);
+ }
+
+ public void accept(DeclarationVisitor visitor)
+ {
+ super.accept(visitor);
+ visitor.visitConstructorDeclaration(this);
+ }
+
+ public MirrorKind kind(){ return MirrorKind.CONSTRUCTOR; }
+}
diff --git a/org.eclipse.jdt.apt.core/src/org/eclipse/jdt/apt/core/internal/declaration/ASTBasedExecutableDeclarationImpl.java b/org.eclipse.jdt.apt.core/src/org/eclipse/jdt/apt/core/internal/declaration/ASTBasedExecutableDeclarationImpl.java
new file mode 100644
index 0000000000..1c1bc986a3
--- /dev/null
+++ b/org.eclipse.jdt.apt.core/src/org/eclipse/jdt/apt/core/internal/declaration/ASTBasedExecutableDeclarationImpl.java
@@ -0,0 +1,111 @@
+/*******************************************************************************
+ * Copyright (c) 2005 BEA Systems, Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * tyeung@bea.com - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.apt.core.internal.declaration;
+
+import java.util.Collection;
+import java.util.List;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.jdt.apt.core.internal.env.BaseProcessorEnv;
+import org.eclipse.jdt.core.dom.SimpleName;
+import org.eclipse.jdt.core.dom.SingleVariableDeclaration;
+import org.eclipse.jdt.core.dom.TypeParameter;
+
+import com.sun.mirror.declaration.ExecutableDeclaration;
+import com.sun.mirror.declaration.ParameterDeclaration;
+import com.sun.mirror.declaration.TypeParameterDeclaration;
+import com.sun.mirror.type.ReferenceType;
+import com.sun.mirror.util.DeclarationVisitor;
+
+public abstract class ASTBasedExecutableDeclarationImpl
+ extends ASTBasedMemberDeclarationImpl
+ implements ExecutableDeclaration{
+
+ public ASTBasedExecutableDeclarationImpl(
+ final org.eclipse.jdt.core.dom.BodyDeclaration astNode,
+ final IFile file,
+ final BaseProcessorEnv env)
+ {
+ super(astNode, file, env);
+ }
+
+ public void accept(DeclarationVisitor visitor)
+ {
+ super.accept(visitor);
+ visitor.visitExecutableDeclaration(this);
+ }
+
+ public Collection<TypeParameterDeclaration> getFormalTypeParameters()
+ {
+ return ExecutableUtil.getFormalTypeParameters(this, _env);
+ }
+
+ public Collection<ParameterDeclaration> getParameters()
+ {
+ return ExecutableUtil.getParameters(this, _env);
+ }
+
+ public Collection<ReferenceType> getThrownTypes()
+ {
+ return ExecutableUtil.getThrownTypes(this, _env);
+ }
+
+ public boolean isVarArgs()
+ {
+ return getMethodAstNode().isVarargs();
+ }
+
+ public String getSimpleName()
+ {
+ final org.eclipse.jdt.core.dom.MethodDeclaration methodAstNode = getMethodAstNode();
+ final SimpleName nameNode = methodAstNode.getName();
+ return nameNode == null ? EMPTY_STRING : nameNode.getIdentifier();
+ }
+
+ org.eclipse.jdt.core.dom.MethodDeclaration getMethodAstNode(){
+ return (org.eclipse.jdt.core.dom.MethodDeclaration)_astNode;
+ }
+
+ public String toString()
+ {
+ final StringBuilder buffer = new StringBuilder();
+ final org.eclipse.jdt.core.dom.MethodDeclaration methodAstNode = getMethodAstNode();
+ @SuppressWarnings("unchecked")
+ final List<TypeParameter> typeParams = methodAstNode.typeParameters();
+ if( typeParams != null && typeParams.size() > 0 ){
+ buffer.append('<');
+ for(int i=0, size=typeParams.size(); i<size; i++ ){
+ if( i != 0 )
+ buffer.append(", "); //$NON-NLS-1$
+ buffer.append(typeParams.get(i).toString());
+ }
+ buffer.append('>');
+ }
+
+ if( methodAstNode.getReturnType2() != null )
+ buffer.append(methodAstNode.getReturnType2());
+ buffer.append(' ');
+ buffer.append(methodAstNode.getName());
+ buffer.append('(');
+ int i=0;
+ @SuppressWarnings("unchecked")
+ final List<SingleVariableDeclaration> params = methodAstNode.parameters();
+ for( SingleVariableDeclaration param : params ){
+ if( i++ != 0 )
+ buffer.append(", "); //$NON-NLS-1$
+ buffer.append(param.getName());
+ }
+ buffer.append(')');
+
+ return buffer.toString();
+ }
+
+}
diff --git a/org.eclipse.jdt.apt.core/src/org/eclipse/jdt/apt/core/internal/declaration/ASTBasedMethodDeclarationImpl.java b/org.eclipse.jdt.apt.core/src/org/eclipse/jdt/apt/core/internal/declaration/ASTBasedMethodDeclarationImpl.java
index b77713f41c..70d4a4f2ef 100644
--- a/org.eclipse.jdt.apt.core/src/org/eclipse/jdt/apt/core/internal/declaration/ASTBasedMethodDeclarationImpl.java
+++ b/org.eclipse.jdt.apt.core/src/org/eclipse/jdt/apt/core/internal/declaration/ASTBasedMethodDeclarationImpl.java
@@ -10,28 +10,18 @@
*******************************************************************************/
package org.eclipse.jdt.apt.core.internal.declaration;
-
-import java.util.Collection;
-import java.util.List;
-
import org.eclipse.core.resources.IFile;
import org.eclipse.jdt.apt.core.internal.env.BaseProcessorEnv;
import org.eclipse.jdt.apt.core.internal.util.Factory;
import org.eclipse.jdt.core.dom.ITypeBinding;
-import org.eclipse.jdt.core.dom.SimpleName;
-import org.eclipse.jdt.core.dom.SingleVariableDeclaration;
import org.eclipse.jdt.core.dom.Type;
-import org.eclipse.jdt.core.dom.TypeParameter;
import com.sun.mirror.declaration.MethodDeclaration;
-import com.sun.mirror.declaration.ParameterDeclaration;
-import com.sun.mirror.declaration.TypeParameterDeclaration;
-import com.sun.mirror.type.ReferenceType;
import com.sun.mirror.type.TypeMirror;
import com.sun.mirror.util.DeclarationVisitor;
public class ASTBasedMethodDeclarationImpl
- extends ASTBasedMemberDeclarationImpl
+ extends ASTBasedExecutableDeclarationImpl
implements MethodDeclaration{
public ASTBasedMethodDeclarationImpl(
@@ -45,37 +35,9 @@ public class ASTBasedMethodDeclarationImpl
public void accept(DeclarationVisitor visitor)
{
super.accept(visitor);
- visitor.visitExecutableDeclaration(this);
visitor.visitMethodDeclaration(this);
}
- public Collection<TypeParameterDeclaration> getFormalTypeParameters()
- {
- return ExecutableUtil.getFormalTypeParameters(this, _env);
- }
-
- public Collection<ParameterDeclaration> getParameters()
- {
- return ExecutableUtil.getParameters(this, _env);
- }
-
- public Collection<ReferenceType> getThrownTypes()
- {
- return ExecutableUtil.getThrownTypes(this, _env);
- }
-
- public boolean isVarArgs()
- {
- return getMethodAstNode().isVarargs();
- }
-
- public String getSimpleName()
- {
- final org.eclipse.jdt.core.dom.MethodDeclaration methodAstNode = getMethodAstNode();
- final SimpleName nameNode = methodAstNode.getName();
- return nameNode == null ? EMPTY_STRING : nameNode.getIdentifier();
- }
-
public TypeMirror getReturnType()
{
final org.eclipse.jdt.core.dom.MethodDeclaration methodAstNode = getMethodAstNode();
@@ -97,42 +59,5 @@ public class ASTBasedMethodDeclarationImpl
}
public MirrorKind kind(){ return MirrorKind.METHOD; }
-
- private org.eclipse.jdt.core.dom.MethodDeclaration getMethodAstNode(){
- return (org.eclipse.jdt.core.dom.MethodDeclaration)_astNode;
- }
-
- public String toString()
- {
- final StringBuilder buffer = new StringBuilder();
- final org.eclipse.jdt.core.dom.MethodDeclaration methodAstNode = getMethodAstNode();
- @SuppressWarnings("unchecked")
- final List<TypeParameter> typeParams = methodAstNode.typeParameters();
- if( typeParams != null && typeParams.size() > 0 ){
- buffer.append('<');
- for(int i=0, size=typeParams.size(); i<size; i++ ){
- if( i != 0 )
- buffer.append(", "); //$NON-NLS-1$
- buffer.append(typeParams.get(i).toString());
- }
- buffer.append('>');
- }
- if( methodAstNode.getReturnType2() != null )
- buffer.append(methodAstNode.getReturnType2());
- buffer.append(' ');
- buffer.append(methodAstNode.getName());
- buffer.append('(');
- int i=0;
- @SuppressWarnings("unchecked")
- final List<SingleVariableDeclaration> params = methodAstNode.parameters();
- for( SingleVariableDeclaration param : params ){
- if( i++ != 0 )
- buffer.append(", "); //$NON-NLS-1$
- buffer.append(param.getName());
- }
- buffer.append(')');
-
- return buffer.toString();
- }
}
diff --git a/org.eclipse.jdt.apt.core/src/org/eclipse/jdt/apt/core/internal/declaration/ClassDeclarationImpl.java b/org.eclipse.jdt.apt.core/src/org/eclipse/jdt/apt/core/internal/declaration/ClassDeclarationImpl.java
index 869b8f0f19..81f213493e 100644
--- a/org.eclipse.jdt.apt.core/src/org/eclipse/jdt/apt/core/internal/declaration/ClassDeclarationImpl.java
+++ b/org.eclipse.jdt.apt.core/src/org/eclipse/jdt/apt/core/internal/declaration/ClassDeclarationImpl.java
@@ -15,8 +15,12 @@ import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
+import org.eclipse.core.resources.IFile;
import org.eclipse.jdt.apt.core.internal.env.BaseProcessorEnv;
import org.eclipse.jdt.apt.core.internal.util.Factory;
+import org.eclipse.jdt.core.dom.ASTNode;
+import org.eclipse.jdt.core.dom.AbstractTypeDeclaration;
+import org.eclipse.jdt.core.dom.BodyDeclaration;
import org.eclipse.jdt.core.dom.IMethodBinding;
import org.eclipse.jdt.core.dom.ITypeBinding;
@@ -42,11 +46,66 @@ public class ClassDeclarationImpl extends TypeDeclarationImpl implements ClassDe
super.accept(visitor);
visitor.visitClassDeclaration(this);
}
+
+ private void getASTConstructor(
+ final AbstractTypeDeclaration typeDecl,
+ final List<ConstructorDeclaration> results){
+
+ final List bodyDecls = typeDecl.bodyDeclarations();
+ for( int i=0, len=bodyDecls.size(); i<len; i++ ){
+ final BodyDeclaration bodyDecl = (BodyDeclaration)bodyDecls.get(i);
+ IFile file = null;
+ if( bodyDecl.getNodeType() == ASTNode.METHOD_DECLARATION ){
+ final org.eclipse.jdt.core.dom.MethodDeclaration methodDecl =
+ (org.eclipse.jdt.core.dom.MethodDeclaration)bodyDecl;
+
+ if( methodDecl.isConstructor() ){
+ final IMethodBinding methodBinding = methodDecl.resolveBinding();
+ // built an ast based representation.
+ if( methodBinding == null ){
+ if( file == null )
+ file = getResource();
+ ConstructorDeclaration mirrorDecl =
+ (ConstructorDeclaration)Factory.createDeclaration(methodDecl, file, _env);
+ if( mirrorDecl != null )
+ results.add(mirrorDecl);
+ }
+ }
+ }
+ }
+ }
public Collection<ConstructorDeclaration> getConstructors()
{
+ final List<ConstructorDeclaration> results = new ArrayList<ConstructorDeclaration>();
+ if( isFromSource() ){
+ // need to consult the ast since methods with broken signature
+ // do not appear in bindings.
+ final ITypeBinding typeBinding = getDeclarationBinding();
+ final ASTNode node =
+ _env.getASTNodeForBinding(typeBinding);
+ if( node != null ){
+ switch( node.getNodeType() )
+ {
+ case ASTNode.TYPE_DECLARATION:
+ case ASTNode.ANNOTATION_TYPE_DECLARATION:
+ case ASTNode.ENUM_DECLARATION:
+ AbstractTypeDeclaration typeDecl =
+ (AbstractTypeDeclaration)node;
+ // built the ast based methods first.
+ getASTConstructor(typeDecl, results);
+ break;
+ default:
+ // the ast node for a type binding should be a AbstractTypeDeclaration.
+ throw new IllegalStateException("expecting a AbstractTypeDeclaration but got " //$NON-NLS-1$
+ + node.getClass().getName() );
+ }
+ }
+ }
+ // build methods for binding type or
+ // build the binding based method for source type.
+
final IMethodBinding[] methods = getDeclarationBinding().getDeclaredMethods();
- final List<ConstructorDeclaration> results = new ArrayList<ConstructorDeclaration>(methods.length);
for( IMethodBinding method : methods ){
if( method.isSynthetic() ) continue;
if( method.isConstructor() ){
diff --git a/org.eclipse.jdt.apt.core/src/org/eclipse/jdt/apt/core/internal/declaration/TypeDeclarationImpl.java b/org.eclipse.jdt.apt.core/src/org/eclipse/jdt/apt/core/internal/declaration/TypeDeclarationImpl.java
index 44f7ac2ac2..799f45ef2d 100644
--- a/org.eclipse.jdt.apt.core/src/org/eclipse/jdt/apt/core/internal/declaration/TypeDeclarationImpl.java
+++ b/org.eclipse.jdt.apt.core/src/org/eclipse/jdt/apt/core/internal/declaration/TypeDeclarationImpl.java
@@ -16,11 +16,18 @@ import java.util.Collection;
import java.util.Collections;
import java.util.List;
+import org.eclipse.core.resources.IFile;
import org.eclipse.jdt.apt.core.internal.env.BaseProcessorEnv;
import org.eclipse.jdt.apt.core.internal.util.Factory;
+import org.eclipse.jdt.core.dom.ASTNode;
+import org.eclipse.jdt.core.dom.AbstractTypeDeclaration;
+import org.eclipse.jdt.core.dom.AnnotationTypeMemberDeclaration;
+import org.eclipse.jdt.core.dom.BodyDeclaration;
+import org.eclipse.jdt.core.dom.IBinding;
import org.eclipse.jdt.core.dom.IMethodBinding;
import org.eclipse.jdt.core.dom.ITypeBinding;
import org.eclipse.jdt.core.dom.IVariableBinding;
+import org.eclipse.jdt.core.dom.VariableDeclarationFragment;
import com.sun.mirror.declaration.*;
import com.sun.mirror.type.DeclaredType;
@@ -65,11 +72,59 @@ public abstract class TypeDeclarationImpl extends MemberDeclarationImpl implemen
}
public ITypeBinding getTypeBinding(){ return (ITypeBinding)_binding; }
+
+ private void getASTFields(
+ final AbstractTypeDeclaration typeDecl,
+ final List<FieldDeclaration> results){
+ final List bodyDecls = typeDecl.bodyDeclarations();
+ for( int i=0, len=bodyDecls.size(); i<len; i++ ){
+ final BodyDeclaration bodyDecl = (BodyDeclaration)bodyDecls.get(i);
+ IFile file = null;
+ if( bodyDecl.getNodeType() == ASTNode.FIELD_DECLARATION ){
+ final List<VariableDeclarationFragment> fragments =
+ ((org.eclipse.jdt.core.dom.FieldDeclaration)bodyDecl).fragments();
+ for( VariableDeclarationFragment frag : fragments ){
+ final IBinding fieldBinding = frag.resolveBinding();
+ if( fieldBinding == null ){
+ if( file == null )
+ file = getResource();
+ final EclipseDeclarationImpl decl = Factory.createDeclaration(frag, file, _env);
+ if( decl != null )
+ results.add((FieldDeclaration)decl);
+ }
+ }
+ }
+ }
+ }
public Collection<FieldDeclaration> getFields()
{
- final IVariableBinding[] fields = getDeclarationBinding().getDeclaredFields();
- final List<FieldDeclaration> results = new ArrayList<FieldDeclaration>(fields.length);
+ final List<FieldDeclaration> results = new ArrayList<FieldDeclaration>();
+ final ITypeBinding typeBinding = getDeclarationBinding();
+ if( isFromSource() ){
+ final ASTNode node =
+ _env.getASTNodeForBinding(typeBinding);
+ if( node != null ){
+ switch( node.getNodeType() )
+ {
+ case ASTNode.TYPE_DECLARATION:
+ case ASTNode.ANNOTATION_TYPE_DECLARATION:
+ case ASTNode.ENUM_DECLARATION:
+ AbstractTypeDeclaration typeDecl =
+ (AbstractTypeDeclaration)node;
+ // built the ast based methods first.
+ getASTFields(typeDecl, results);
+ break;
+ default:
+ // the ast node for a type binding should be a AbstractTypeDeclaration.
+ throw new IllegalStateException("expecting a AbstractTypeDeclaration but got " //$NON-NLS-1$
+ + node.getClass().getName() );
+ }
+ }
+ }
+ // either type is binary or
+ // constructing the binding based fields for source type.
+ final IVariableBinding[] fields = typeBinding.getDeclaredFields();
for( IVariableBinding field : fields ){
// note that the name HAS_INCONSISTENT_TYPE_HIERACHY is not a legal java identifier
// so there is no chance that we are filtering out actual declared fields.
@@ -179,11 +234,83 @@ public abstract class TypeDeclarationImpl extends MemberDeclarationImpl implemen
final ITypeBinding type = getTypeBinding();
return type.getTypeDeclaration();
}
+
+ /**
+ * create mirror methods that does not have a binding represention.
+ */
+ protected void getASTMethods(
+ final AbstractTypeDeclaration typeDecl,
+ final List<MethodDeclaration> results){
+ final List bodyDecls = typeDecl.bodyDeclarations();
+ for( int i=0, len=bodyDecls.size(); i<len; i++ ){
+ final BodyDeclaration bodyDecl = (BodyDeclaration)bodyDecls.get(i);
+ IFile file = null;
+ switch(bodyDecl.getNodeType()){
+ case ASTNode.METHOD_DECLARATION:
+ final org.eclipse.jdt.core.dom.MethodDeclaration methodDecl =
+ (org.eclipse.jdt.core.dom.MethodDeclaration)bodyDecl;
+
+ if( !methodDecl.isConstructor() ){
+ final IMethodBinding methodBinding = methodDecl.resolveBinding();
+ // built an ast based representation.
+ if( methodBinding == null ){
+ if( file == null )
+ file = getResource();
+ MethodDeclaration mirrorDecl =
+ (MethodDeclaration)Factory.createDeclaration(methodDecl, file, _env);
+ if( mirrorDecl != null )
+ results.add(mirrorDecl);
+ }
+ }
+ break;
+ case ASTNode.ANNOTATION_TYPE_MEMBER_DECLARATION:
+ final AnnotationTypeMemberDeclaration memberDecl =
+ (AnnotationTypeMemberDeclaration)bodyDecl;
+ final IMethodBinding methodBinding = memberDecl.resolveBinding();
+ // built an ast based representation.
+ if( methodBinding == null ){
+ if( file == null )
+ file = getResource();
+ MethodDeclaration mirrorDecl =
+ (MethodDeclaration)Factory.createDeclaration(memberDecl, file, _env);
+ if( mirrorDecl != null )
+ results.add(mirrorDecl);
+ }
+ break;
+ }
+ }
+ }
protected List<? extends MethodDeclaration> _getMethods()
{
- final IMethodBinding[] methods = getDeclarationBinding().getDeclaredMethods();
- final List<MethodDeclaration> results = new ArrayList<MethodDeclaration>(methods.length);
+ final List<MethodDeclaration> results = new ArrayList<MethodDeclaration>();
+ if( isFromSource() ){
+ // need to consult the ast since methods with broken signature
+ // do not appear in bindings.
+ final ITypeBinding typeBinding = getDeclarationBinding();
+ final ASTNode node =
+ _env.getASTNodeForBinding(typeBinding);
+ if( node != null ){
+ switch( node.getNodeType() )
+ {
+ case ASTNode.TYPE_DECLARATION:
+ case ASTNode.ANNOTATION_TYPE_DECLARATION:
+ case ASTNode.ENUM_DECLARATION:
+ AbstractTypeDeclaration typeDecl =
+ (AbstractTypeDeclaration)node;
+ // built the ast based methods first.
+ getASTMethods(typeDecl, results);
+ break;
+ default:
+ // the ast node for a type binding should be a AbstractTypeDeclaration.
+ throw new IllegalStateException("expecting a AbstractTypeDeclaration but got " //$NON-NLS-1$
+ + node.getClass().getName() );
+ }
+ }
+ }
+ // build methods for binding type or
+ // build the binding based method for source type.
+ final IMethodBinding[] methods = getDeclarationBinding().getDeclaredMethods();
for( IMethodBinding method : methods ){
if( method.isConstructor() || method.isSynthetic() ) continue;
Declaration mirrorDecl = Factory.createDeclaration(method, _env);
diff --git a/org.eclipse.jdt.apt.core/src/org/eclipse/jdt/apt/core/internal/env/BaseProcessorEnv.java b/org.eclipse.jdt.apt.core/src/org/eclipse/jdt/apt/core/internal/env/BaseProcessorEnv.java
index 121f2107d7..5648e6b41c 100644
--- a/org.eclipse.jdt.apt.core/src/org/eclipse/jdt/apt/core/internal/env/BaseProcessorEnv.java
+++ b/org.eclipse.jdt.apt.core/src/org/eclipse/jdt/apt/core/internal/env/BaseProcessorEnv.java
@@ -98,6 +98,8 @@ public class BaseProcessorEnv implements AnnotationProcessorEnvironment
private static final int SHORT_INDEX = 7;
private static final int VOID_INDEX = 8;
+ private static final String DOT_JAVA = ".java"; //$NON-NLS-1$
+
protected CompilationUnit _astRoot;
protected final Phase _phase;
protected IFile _file;
@@ -203,7 +205,7 @@ public class BaseProcessorEnv implements AnnotationProcessorEnvironment
if( type == null ) return;
typeBindings.add(type);
for( ITypeBinding nestedType : type.getDeclaredTypes() ) {
- typeBindings.add(nestedType);
+ //typeBindings.add(nestedType);
getTypeBindings(nestedType, typeBindings);
}
}
@@ -371,7 +373,7 @@ public class BaseProcessorEnv implements AnnotationProcessorEnvironment
return Factory.createReferenceType(typeBinding, this);
// finally go search for it in the universe.
- typeBinding = getTypeBinding(typeKey);
+ typeBinding = getTypeDefinitionBindingFromName(name);
if( typeBinding != null ){
return Factory.createReferenceType(typeBinding, this);
}
@@ -380,14 +382,45 @@ public class BaseProcessorEnv implements AnnotationProcessorEnvironment
}
/**
- * @param key the key to a type binding, could be reference type, array or primitive.
- * @return the binding corresponding to the given key or null if none is found.
- */
- public ITypeBinding getTypeBinding(final String key)
- {
+ * @param fullyQualifiedName the fully qualified name of a type.
+ * The name cannot contain type argument or array signature.
+ * @return the type binding corresponding to the parameter.
+ */
+ ITypeBinding getTypeDefinitionBindingFromName(
+ final String fullyQualifiedName ){
+ final int dollarIndex = fullyQualifiedName.indexOf('$');
+ final String toplevelTypeName;
+ if( dollarIndex < 0 )
+ toplevelTypeName = fullyQualifiedName;
+ else
+ toplevelTypeName = fullyQualifiedName.substring(0, dollarIndex);
+
+ // locate the compilation unit for the type of interest.
+ // we need this information so that when we request the binding for 'fullyQualifiedName'
+ // we can get the dom pipeline to return back to us the ast compilation unit
+ // which we will need to correctly compute the number of methods, fields and constructors.
+ // see CR259011 -theodora
+ ICompilationUnit unit = getICompilationUnitForTopLevelType(toplevelTypeName);
+ final String key = BindingKey.createTypeBindingKey(fullyQualifiedName);
+ return getTypeBindingFromKey(key, unit);
+ }
+
+ /**
+ * @param key
+ * @param unit the unit that contains the definition of type whose type key is <code>key</code>
+ * if <code>key</code> is a wild card, primitive, array type or parameterized type, this should be null.
+ * @return return the type binding for the given key or null if none is found.
+ */
+ private ITypeBinding getTypeBindingFromKey(final String key, final ICompilationUnit unit){
+
class BindingRequestor extends ASTRequestor
{
private ITypeBinding _result = null;
+ public void acceptAST(ICompilationUnit source, CompilationUnit ast) {
+ if( source == unit ){
+ _modelCompUnit2astCompUnit.put(source, ast);
+ }
+ }
public void acceptBinding(String bindingKey, IBinding binding)
{
if( binding != null && binding.getKind() == IBinding.TYPE )
@@ -399,8 +432,28 @@ public class BaseProcessorEnv implements AnnotationProcessorEnvironment
final ASTParser parser = ASTParser.newParser(AST.JLS3);
parser.setResolveBindings(true);
parser.setProject(_javaProject);
- parser.createASTs(NO_UNIT, new String[]{key}, requestor, null);
- return requestor._result;
+ ICompilationUnit[] units = unit == null ? NO_UNIT : new ICompilationUnit[]{unit};
+ parser.createASTs(units, new String[]{key}, requestor, null);
+ final ITypeBinding result = requestor._result;
+ if(result != null && unit != null){
+ final CompilationUnit astUnit = _modelCompUnit2astCompUnit.get(unit);
+ // make sure everything is lining up properly.
+ if( astUnit.findDeclaringNode(result) != null ){
+ ITypeBinding declaringClass = getDeclaringClass(result);
+ _typeBinding2ModelCompUnit.put(declaringClass, unit);
+ }
+ }
+ return result;
+ }
+
+ /**
+ * @param key the key to a type binding, could be reference type, array or primitive.
+ * @return the binding corresponding to the given key or null if none is found.
+ */
+ public ITypeBinding getTypeBindingFromKey(final String key)
+ {
+ return getTypeBindingFromKey(key, null);
+
}
public TypeDeclaration getTypeDeclaration(final IType type) {
@@ -500,6 +553,28 @@ public class BaseProcessorEnv implements AnnotationProcessorEnvironment
return _astRoot;
return null;
}
+
+ /**
+ * Retrieve the <code>ICompilationUnit</code> whose top-level type has
+ * <code>topTypeQName</code> as its fully qualified name.
+ * @param topTypeQName
+ * @return the <code>ICompilationUnit</code> matching <code>topTypeQName</code> or
+ * <code>null</code> if one doesn't exist.
+ */
+ private ICompilationUnit getICompilationUnitForTopLevelType(final String topTypeQName ){
+ final String pathname = topTypeQName.replace('.', File.separatorChar) + DOT_JAVA;
+ final IPath path = Path.fromOSString(pathname);
+ try{
+ final IJavaElement element = _javaProject.findElement(path);
+ if( element instanceof ICompilationUnit )
+ return (ICompilationUnit)element;
+ else // dropping class files.
+ return null;
+ }
+ catch(JavaModelException e){
+ return null;
+ }
+ }
/**
* @param binding must be correspond to a type, method or field declaration.
@@ -521,19 +596,14 @@ public class BaseProcessorEnv implements AnnotationProcessorEnvironment
}
else{
final ITypeBinding typeBinding = getDeclaringClass(binding);
+ // binary type don't have compilation unit.
+ if( !typeBinding.isFromSource() )
+ return null;
if( _typeBinding2ModelCompUnit.get(typeBinding) != null )
unit = _typeBinding2ModelCompUnit.get(typeBinding);
else{
final String qname = typeBinding.getQualifiedName();
- final String pathname = qname.replace('.', File.separatorChar);
- final IPath path = Path.fromOSString(pathname);
- try{
- unit = (ICompilationUnit)_javaProject.findElement(path);
- _typeBinding2ModelCompUnit.put(typeBinding, unit);
- }
- catch(JavaModelException e){
- throw new IllegalStateException(e);
- }
+ unit = getICompilationUnitForTopLevelType(qname);
}
}
if( unit == null ) return null;
@@ -621,18 +691,14 @@ public class BaseProcessorEnv implements AnnotationProcessorEnvironment
else{
final ITypeBinding type = getDeclaringClass(binding);
assert type.isTopLevel() : "type must be top-level type"; //$NON-NLS-1$
+ ICompilationUnit unit = _typeBinding2ModelCompUnit.get(type);
+ if( unit != null )
+ return (IFile)unit.getResource();
final String qname = type.getQualifiedName();
- final String pathname = qname.replace('.', File.separatorChar);
- final IPath path = Path.fromOSString(pathname);
- try{
- // the element would be a compilation unit.
- final IJavaElement element = _javaProject.findElement(path);
- if( element == null ) return null;
- return (IFile)element.getResource();
- }
- catch(JavaModelException e){
- throw new IllegalStateException(e);
- }
+ unit = getICompilationUnitForTopLevelType(qname);
+ if( unit == null )
+ return null;
+ return (IFile)unit.getResource();
}
}
diff --git a/org.eclipse.jdt.apt.core/src/org/eclipse/jdt/apt/core/internal/env/BinaryFileOutputStream.java b/org.eclipse.jdt.apt.core/src/org/eclipse/jdt/apt/core/internal/env/BinaryFileOutputStream.java
index 3377f386b5..1c4f80eb82 100644
--- a/org.eclipse.jdt.apt.core/src/org/eclipse/jdt/apt/core/internal/env/BinaryFileOutputStream.java
+++ b/org.eclipse.jdt.apt.core/src/org/eclipse/jdt/apt/core/internal/env/BinaryFileOutputStream.java
@@ -105,8 +105,14 @@ public class BinaryFileOutputStream extends ByteArrayOutputStream {
}
}
catch (CoreException ce) {
- AptPlugin.log(ce, "Could not create generated file"); //$NON-NLS-1$
- throw new IOException(ce.getMessage());
+ if (_file.exists()) {
+ // Do nothing. This is a case-insensitive file system mismatch,
+ // and the underlying platform has saved the contents already.
+ }
+ else {
+ AptPlugin.log(ce, "Could not create generated file"); //$NON-NLS-1$
+ throw new IOException(ce.getMessage());
+ }
}
}
diff --git a/org.eclipse.jdt.apt.core/src/org/eclipse/jdt/apt/core/internal/env/ProcessorEnvImpl.java b/org.eclipse.jdt.apt.core/src/org/eclipse/jdt/apt/core/internal/env/ProcessorEnvImpl.java
index 7e60e6c7c8..f673b4acd2 100644
--- a/org.eclipse.jdt.apt.core/src/org/eclipse/jdt/apt/core/internal/env/ProcessorEnvImpl.java
+++ b/org.eclipse.jdt.apt.core/src/org/eclipse/jdt/apt/core/internal/env/ProcessorEnvImpl.java
@@ -181,7 +181,7 @@ public class ProcessorEnvImpl extends CompilationProcessorEnv
}
// finally go search for it in the universe.
- typeBinding = getTypeBinding(typeKey);
+ typeBinding = getTypeDefinitionBindingFromName(name);
if( typeBinding != null ){
return Factory.createReferenceType(typeBinding, this);
}
diff --git a/org.eclipse.jdt.apt.core/src/org/eclipse/jdt/apt/core/internal/generatedfile/ClasspathUtil.java b/org.eclipse.jdt.apt.core/src/org/eclipse/jdt/apt/core/internal/generatedfile/ClasspathUtil.java
index 6f2faffe65..1d8e293bad 100644
--- a/org.eclipse.jdt.apt.core/src/org/eclipse/jdt/apt/core/internal/generatedfile/ClasspathUtil.java
+++ b/org.eclipse.jdt.apt.core/src/org/eclipse/jdt/apt/core/internal/generatedfile/ClasspathUtil.java
@@ -61,7 +61,7 @@ public class ClasspathUtil {
* @return
* @throws JavaModelException
*/
- public static boolean isProjectClassPathUpToDate(
+ public static boolean doesClasspathContainEntry(
IJavaProject jp,
IClasspathEntry[] cp,
IPath path,
@@ -88,7 +88,7 @@ public class ClasspathUtil {
{
IClasspathEntry[] cp = jp.getRawClasspath();
IPath workspaceRelativePath = folder.getFullPath();
- boolean found = isProjectClassPathUpToDate(jp, cp, workspaceRelativePath, progressMonitor);
+ boolean found = doesClasspathContainEntry(jp, cp, workspaceRelativePath, progressMonitor);
if( found ){
IPath projectRelativePath = folder.getProjectRelativePath().addTrailingSeparator();
@@ -150,7 +150,7 @@ public class ClasspathUtil {
{
IClasspathEntry[] cp = jp.getRawClasspath();
IPath path = folder.getFullPath();
- boolean found = ClasspathUtil.isProjectClassPathUpToDate(jp, cp, path, progressMonitor);
+ boolean found = ClasspathUtil.doesClasspathContainEntry(jp, cp, path, progressMonitor);
if (!found)
{
diff --git a/org.eclipse.jdt.apt.core/src/org/eclipse/jdt/apt/core/internal/generatedfile/GeneratedFileManager.java b/org.eclipse.jdt.apt.core/src/org/eclipse/jdt/apt/core/internal/generatedfile/GeneratedFileManager.java
index f28eb4ac48..2488731487 100644
--- a/org.eclipse.jdt.apt.core/src/org/eclipse/jdt/apt/core/internal/generatedfile/GeneratedFileManager.java
+++ b/org.eclipse.jdt.apt.core/src/org/eclipse/jdt/apt/core/internal/generatedfile/GeneratedFileManager.java
@@ -778,11 +778,11 @@ public class GeneratedFileManager {
AptPlugin.log(e, "Unable to delete configuration marker."); //$NON-NLS-1$
}
_skipTypeGeneration = false;
- _gsfm.createGeneratedSourceFolder();
+ _gsfm.ensureFolderExists();
final IFolder genFolder;
synchronized(this){
genFolder = _gsfm.getFolder();
- _snapshotFolderName = _gsfm.getFolderName();
+ _snapshotFolderName = genFolder.getProjectRelativePath().toString();
}
try {
_generatedPackageFragmentRoot = null;
diff --git a/org.eclipse.jdt.apt.core/src/org/eclipse/jdt/apt/core/internal/generatedfile/GeneratedResourceChangeListener.java b/org.eclipse.jdt.apt.core/src/org/eclipse/jdt/apt/core/internal/generatedfile/GeneratedResourceChangeListener.java
index 9f3be3b1ec..75bbed4371 100644
--- a/org.eclipse.jdt.apt.core/src/org/eclipse/jdt/apt/core/internal/generatedfile/GeneratedResourceChangeListener.java
+++ b/org.eclipse.jdt.apt.core/src/org/eclipse/jdt/apt/core/internal/generatedfile/GeneratedResourceChangeListener.java
@@ -72,13 +72,13 @@ public class GeneratedResourceChangeListener implements IResourceChangeListener
}
}
-private void addGeneratedSrcFolderTo(final Set<IProject> projs ){
+ private void addGeneratedSrcFolderTo(final Set<IProject> projs ){
for(IProject proj : projs ){
final IJavaProject javaProj = JavaCore.create(proj);
if(AptConfig.isEnabled(javaProj)){
final GeneratedSourceFolderManager gsfm = AptPlugin.getAptProject(javaProj).getGeneratedSourceFolderManager();
- gsfm.createGeneratedSourceFolder();
+ gsfm.ensureFolderExists();
}
}
@@ -117,7 +117,7 @@ private void addGeneratedSrcFolderTo(final Set<IProject> projs ){
final GeneratedSourceFolderManager gsfm = aptProj.getGeneratedSourceFolderManager();
IFolder f = (IFolder) r;
if ( gsfm.isGeneratedSourceFolder( f ) ){
- gsfm.generatedSourceFolderDeleted();
+ gsfm.folderDeleted();
// all deletion occurs before any add (adding the generated source directory)
if( !_removedProjects.contains(project) ){
_addGenFolderTo.add(project);
diff --git a/org.eclipse.jdt.apt.core/src/org/eclipse/jdt/apt/core/internal/generatedfile/GeneratedSourceFolderManager.java b/org.eclipse.jdt.apt.core/src/org/eclipse/jdt/apt/core/internal/generatedfile/GeneratedSourceFolderManager.java
index 7d728a16ea..142a57716b 100644
--- a/org.eclipse.jdt.apt.core/src/org/eclipse/jdt/apt/core/internal/generatedfile/GeneratedSourceFolderManager.java
+++ b/org.eclipse.jdt.apt.core/src/org/eclipse/jdt/apt/core/internal/generatedfile/GeneratedSourceFolderManager.java
@@ -11,20 +11,15 @@
package org.eclipse.jdt.apt.core.internal.generatedfile;
-import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IResource;
-import org.eclipse.core.resources.IWorkspace;
-import org.eclipse.core.resources.IWorkspaceRunnable;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
-import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.core.runtime.OperationCanceledException;
+import org.eclipse.core.runtime.IStatus;
import org.eclipse.jdt.apt.core.AptPlugin;
import org.eclipse.jdt.apt.core.internal.AptProject;
import org.eclipse.jdt.apt.core.internal.util.FileSystemUtil;
import org.eclipse.jdt.apt.core.util.AptConfig;
-import org.eclipse.jdt.apt.core.util.AptPreferenceConstants;
import org.eclipse.jdt.core.IClasspathEntry;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.JavaModelException;
@@ -47,7 +42,7 @@ import org.eclipse.jdt.core.JavaModelException;
* </ul>
* We attempt to change the classpath entry and the folder on disk whenever
* the enabled/disabled state or the folder name change. These changes are
- * discovered via the handlePreferenceChange() method.
+ * discovered via the preferenceChanged() method.
* <p>
* GeneratedSourceFolderManager is responsible only for the folder itself, not
* its contents. Contents are managed by @see GeneratedFileManager.
@@ -58,21 +53,26 @@ public class GeneratedSourceFolderManager {
private final AptProject _aptProject;
/**
- * The folder where generated source files are placed. This will be null until
- * the folder is actually created and the project's source path is updated to
- * include the folder. It will also be null if there was an error creating the
- * folder.
+ * The folder where generated source files are placed. This will be
+ * null if APT is disabled, or in any other error state (e.g., folder
+ * does not exist on disk; folder exists on disk but classpath entry
+ * does not exist).
+ * <p>
+ * In general, if we see that this member is null but the ENABLED
+ * preference is true, we will try to create the folder and add it to
+ * the classpath; if we see that this member is non-null but the
+ * ENABLED preference is false, we will try to delete this folder's
+ * contents and remove it from the classpath; and if we see that the
+ * ENABLED preference is true, but the GENSRCDIR folder name preference
+ * is different than the name of this folder, we will try to delete
+ * this folder's contents, remove it from the classpath, and create a
+ * new folder and add it to the classpath. When we do this work depends
+ * on when we get notified of relevant changes and on what locks we are
+ * able to obtain.
*/
private IFolder _generatedSourceFolder = null;
/**
- * The name of the generated source folder, relative to the project. This
- * will be identical to the value of the APT_GENSRCDIR preference, except when
- * the preference has changed and this object has not yet been informed.
- */
- private String _generatedSourceFolderName = null;
-
- /**
* Should be constructed only by AptProject. Other clients should call
* @see AptProject#getGeneratedSourceFolderManager() to get this object.
*/
@@ -81,244 +81,219 @@ public class GeneratedSourceFolderManager {
_aptProject = aptProject;
final IJavaProject javaProject = aptProject.getJavaProject();
- // get generated source dir from config
- // default value is set in org.eclipse.jdt.apt.core.internal.util.AptCorePreferenceInitializer
- _generatedSourceFolderName = AptConfig.getString( javaProject, AptPreferenceConstants.APT_GENSRCDIR);
- // properly initialize the GeneratedFileManager if project path is up-to-date and the generated
- // source folder is there.
- final IFolder folder = getFolder();
- if(folder.exists()){
- boolean uptodate = false;
- try{
- uptodate = ClasspathUtil.isProjectClassPathUpToDate(javaProject, null, folder.getFullPath(), null);
- }catch(JavaModelException e){
- e.printStackTrace();
+ // Set _generatedSourceFolder only if APT is enabled, the folder exists,
+ // and the folder is on the classpath.
+ // Otherwise leave it null, which will cause us to try to fix things later on.
+ if (AptConfig.isEnabled(javaProject)) {
+ final IFolder folder = getFolder();
+ if (folder.exists()) {
+ if (isOnClasspath(folder)) {
+ _generatedSourceFolder = folder;
+ }
}
- if( uptodate )
- _generatedSourceFolder = folder;
- }
+ }
}
/**
- * Sets the name of the generated soruce folder. The source folder will not be created
- * and will not be added to the project's source paths. If there is an existing source
- * folder, it will be deleted.
- * To properly have the new generated source folder configured, call #ensureGeneratedSourceFolder().
- *
- * @param newValue The string name of the new generated source folder. This should be relative
- * to the project root. Absolute paths are not supported. The specified string should be
- * a valid folder name for the file system, and should not be an existing source folder for the
- * project.
- *
- * @see #getFolder()
- * @see #getFolderName()
+ * Add the folder to the classpath, unless it's already there.
+ * @param srcFolder the folder to add to the classpath. Must not be null.
+ * @return true if, at the end of the routine, the folder is on the classpath.
*/
- private void configure( String newValue, String oldValue )
- {
-
- // bail if they specify null, empty-string or don't change the name of the source folder
- if ( newValue == null ||
- newValue.length() == 0 ||
- newValue.equals(oldValue) )
- return;
-
- _aptProject.projectClean( true );
-
- IFolder srcFolder = null;
- synchronized ( this )
- {
- _generatedSourceFolderName = newValue;
- srcFolder = _generatedSourceFolder;
+ private boolean addToClasspath(IFolder srcFolder) {
+ boolean onClasspath = false;
+ try {
+ ClasspathUtil.updateProjectClasspath( _aptProject.getJavaProject(), srcFolder, null );
+ if(AptPlugin.DEBUG)
+ AptPlugin.trace("Ensured classpath has an entry for " + srcFolder); //$NON-NLS-1$
+ onClasspath = true;
}
-
- // if the preference change occur before we actually
- // initialized the _generatedSourceFolder.
- // This may happen when the pre-processor resource change event occurs after
- // the preference change event.
- if( oldValue != null && srcFolder == null ){
- srcFolder = _aptProject.getJavaProject().getProject().getFolder( oldValue );
+ catch (CoreException e) {
+ e.printStackTrace();
+ AptPlugin.log(e, "Failed to add classpath entry for generated source folder " + srcFolder.getName()); //$NON-NLS-1$
}
-
- resetGeneratedSrcFolder(srcFolder, true);
+ return onClasspath;
}
/**
- * Creates the generated source folder if it doesn't exist.
- * No changes to the classpath will be made.
+ * Call this to create the folder and add it to the classpath, when APT is enabled
+ * (in which case the folder did not previously exist) or when the folder name is
+ * changed (in which case the old stuff must also be removed).
+ * <p>
+ * This method will take a resource lock if the generated source folder needs
+ * to be created on disk, and it will take a java model lock if the project's
+ * source paths need to be updated. Care should be taken when calling this
+ * method to ensure that locking behavior is correct.
+ * <p>
+ * This should only be called on an event thread, with no locks on the project
+ * or classpath.
*/
- public void createGeneratedSourceFolder(){
- IFolder srcFolder = getFolder();
- // This most likely means the preference change event hasn't occured yet
- // and we don't know about the name of the generated source directory.
- if( srcFolder == null )
+ private void configure() {
+
+ assert(_generatedSourceFolder == null): "Should have already removed old folder by now"; //$NON-NLS-1$
+ IFolder srcFolder = getFolderPreference();
+ if (srcFolder == null) {
+ IStatus status = AptPlugin.createStatus(null, "Could not create generated source folder (" + //$NON-NLS-1$
+ AptConfig.getGenSrcDir(_aptProject.getJavaProject()) + ")"); //$NON-NLS-1$
+ AptPlugin.log(status);
return;
- try{
- srcFolder.refreshLocal( IResource.DEPTH_INFINITE, null );
- if (!srcFolder.exists()) {
- if( AptPlugin.DEBUG )
- AptPlugin.trace("creating " + srcFolder.getProjectRelativePath()); //$NON-NLS-1$
-
- FileSystemUtil.makeDerivedParentFolders(srcFolder);
- }
- }
- catch(CoreException ce){
- AptPlugin.log(ce, "Failure during refreshLocal on " + srcFolder.getProjectRelativePath()); //$NON-NLS-1$
}
- synchronized (this) {
- _generatedSourceFolder = srcFolder;
+
+ // Ensure that the new folder exists on disk.
+ if (createOnDisk(srcFolder)) {
+ // Add it to the classpath.
+ if (addToClasspath(srcFolder)) {
+ // Only if we get this far do we actually set _generatedSourceFolder.
+ synchronized ( this ) {
+ _generatedSourceFolder = srcFolder;
+ }
+ }
}
}
+
/**
- * Creates the generated source folder if it doesn't exist, and adds it as a source path
- * to the project. To access the generated source folder, but not have it be created
- * or added as a source path, use getGeneratedSourceFolder(). Note that this method
- * will take a resource lock if the generated source folder needs to be created on disk,
- * and it will take a java model lock if the project's source paths need to be updated.
- * Care should be taken when calling this method to ensure that locking behavior is correct.
- *
- * @return <code>true</code> iff the any resource or classpath has been modified.
- * return <code>false</code> otherwise.
- *
- * @see #getFolder()
- * @see #isGeneratedSourceFolderConfigured()
+ * Creates the generated source folder if necessary. This should be called just
+ * before doing a build.
+ * No changes to the classpath will be made.
*/
- private boolean ensureGeneratedSourceFolder(){
+ public void ensureFolderExists(){
+ // If APT is disabled, do nothing.
+ if (!AptConfig.isEnabled(_aptProject.getJavaProject())) {
+ return;
+ }
- boolean reset = false;
- IFolder curSrcFolder = null;
-
- // Determine current state of affairs, with respect to
- // folder, folder name, and classpath.
- synchronized( this )
- {
- if( _generatedSourceFolder != null ){
- final IPath srcFolderPath = _generatedSourceFolder.getProjectRelativePath();
-
- if( !_generatedSourceFolderName.equals( srcFolderPath.toString()) ){
- // Folder name has been changed! Save the current folder so we can clear it out later.
- reset = true;
- curSrcFolder = _generatedSourceFolder;
- _generatedSourceFolder = null;
- }
- else {
- // Folder name and folder are in sync. Check that folder is on classpath.
-
- // If the folder doesn't exist on disk, there is no point examining the classpath.
- try{
- _generatedSourceFolder.refreshLocal( IResource.DEPTH_INFINITE, null );
- }
- catch(CoreException ce){
- AptPlugin.log(ce, "Failure during refreshLocal on " + srcFolderPath); //$NON-NLS-1$
- }
- if (!_generatedSourceFolder.exists()) {
- return false;
- }
-
- try {
- IJavaProject jp = _aptProject.getJavaProject();
- IClasspathEntry[] cp = jp.getRawClasspath();
- IPath path = _generatedSourceFolder.getFullPath();
- if (ClasspathUtil.isProjectClassPathUpToDate(jp, cp, path, null)) {
- return false;
- }
- }
- catch (JavaModelException jme) {
- AptPlugin.log(jme, "Failure examining the classpath"); //$NON-NLS-1$
- }
- }
- }
+ // In principle we could bail out here, if (_generatedSourceFolder != null).
+ // However, this method is an opportunity to detect and fix problems such
+ // as the folder getting deleted without generatedSourceFolderDeleted()
+ // getting called (e.g., without user having done a refresh).
+ IFolder srcFolder = getFolder();
+ if (srcFolder == null) {
+ IStatus status = AptPlugin.createStatus(null, "Could not create generated source folder (" + //$NON-NLS-1$
+ AptConfig.getGenSrcDir(_aptProject.getJavaProject()) + ")"); //$NON-NLS-1$
+ AptPlugin.log(status);
+ return;
}
- IFolder srcFolder = null;
- try{
- if( reset ){
- // Folder name was out of sync with folder. Delete the old folder and classpath entry.
- ClasspathUtil.removeFromProjectClasspath(_aptProject.getJavaProject(), curSrcFolder, null );
- if ( curSrcFolder.exists() ){
- if( AptPlugin.DEBUG )
- AptPlugin.trace("deleting gen src dir " + curSrcFolder.getName() ); //$NON-NLS-1$
- curSrcFolder.delete( true, false, null );
+ if (createOnDisk(srcFolder)) {
+ if (isOnClasspath(srcFolder)) {
+ synchronized (this) {
+ // Only set _generatedSourceFolder if folder is on disk and on classpath.
+ _generatedSourceFolder = srcFolder;
}
}
-
+ }
+ }
+
+ /**
+ * Create a folder on disk, unless it already exists.
+ * <p>
+ * This method will frequently be called on multiple threads simultaneously
+ * (e.g., build thread and UI thread).
+ * @param srcFolder the folder to create. Must not be null.
+ * @return true if, at the end of the routine, the folder exists on disk.
+ */
+ private boolean createOnDisk(IFolder srcFolder) {
+ boolean exists = false;
+ try {
// don't take any locks while creating the folder, since we are doing file-system operations
- srcFolder = getFolder();
srcFolder.refreshLocal( IResource.DEPTH_INFINITE, null );
if (!srcFolder.exists()) {
FileSystemUtil.makeDerivedParentFolders(srcFolder);
+ if(AptPlugin.DEBUG)
+ AptPlugin.trace("Created folder " + srcFolder + " on disk"); //$NON-NLS-1$ //$NON-NLS-2$
}
-
- //
- // make sure __generated_src dir is on the cp if not already
- //
- ClasspathUtil.updateProjectClasspath( _aptProject.getJavaProject(), srcFolder, null );
-
- if(AptPlugin.DEBUG)
- AptPlugin.trace("Added directory " + srcFolder.getName() + " and updated classpath" ); //$NON-NLS-1$ //$NON-NLS-2$
+ exists = true;
}
- catch(CoreException e){
+ catch (CoreException e) {
e.printStackTrace();
- AptPlugin.log(e, "Failed to create generated source directory"); //$NON-NLS-1$
- return false;
+ AptPlugin.log(e, "Failed to ensure existence of generated source folder " + srcFolder.getName()); //$NON-NLS-1$
+ }
+ return exists;
+ }
+
+ /**
+ * Call this method when the APT_ENABLED preference has changed.
+ *
+ * Configure the generated source folder according to whether APT is enabled
+ * or disabled. If enabled, the folder will be created and a classpath entry
+ * will be added. If disabled, the folder and classpath entry will be removed.
+ * <p>
+ * This should only be called on an event thread, with no locks on the project
+ * or classpath.
+ * @param enable
+ */
+ public void enabledPreferenceChanged()
+ {
+ final boolean enable = AptConfig.isEnabled(_aptProject.getJavaProject());
+ // Short-circuit if nothing changed.
+ if (enable == (_generatedSourceFolder != null)) {
+ if( AptPlugin.DEBUG ) {
+ AptPlugin.trace("enabledChanged() doing nothing; state is already " + enable); //$NON-NLS-1$
+ }
+ // no change in state
+ return;
}
- synchronized ( this )
- {
- _generatedSourceFolder = srcFolder;
- return true;
+ if ( AptPlugin.DEBUG ) {
+ AptPlugin.trace("enabledChanged() changing state to " + enable + //$NON-NLS-1$
+ " for " + _aptProject.getJavaProject().getElementName()); //$NON-NLS-1$
+ }
+ if( enable ) {
+ configure();
+ }
+ else {
+ removeFolder();
}
}
-
+
+ /**
+ * Respond to a change in the name of the generated source folder.
+ * If APT is enabled, remove the old folder and classpath entry and
+ * create new ones.
+ * <p>
+ * This should only be called on an event thread, with no locks on the project
+ * or classpath.
+ */
+ public void folderNamePreferenceChanged()
+ {
+ // if APT is disabled, we don't need to do anything
+ final boolean aptEnabled = AptConfig.isEnabled(_aptProject.getJavaProject());
+ if (!aptEnabled) {
+ return;
+ }
+
+ // if name didn't change, we don't need to do anything
+ if (_generatedSourceFolder != null && _generatedSourceFolder.equals(getFolderPreference())) {
+ if( AptPlugin.DEBUG ) {
+ AptPlugin.trace("folderNameChanged() doing nothing; name is already " + //$NON-NLS-1$
+ _generatedSourceFolder.getProjectRelativePath());
+ }
+ return;
+ }
+
+ removeFolder();
+ configure();
+ }
/**
* Invoked when the generated source folder has been deleted. This will
- * flush any in-memory state tracking generated files and clean up the project classpath.
+ * flush any in-memory state tracking generated files, and cause the
+ * generated source folder to be recreated the next time we build.
*
* Note: this should only be called within a resource change event to ensure that the classpath
* is correct during any build. Resource change event never occurs during a build.
*/
- public void generatedSourceFolderDeleted()
+ public void folderDeleted()
{
_aptProject.projectClean( false );
IFolder srcFolder;
synchronized(this){
- srcFolder = getFolder();
+ srcFolder = _generatedSourceFolder;
_generatedSourceFolder = null;
}
if(AptPlugin.DEBUG)
- AptPlugin.trace("nulled out gen src dir " + srcFolder.getName() ); //$NON-NLS-1$
- }
-
- /**
- * @return get the generated source folder. May return null if
- * creation has failed, the folder has been deleted or has not been created.
- */
- public IFolder getFolder(){
-
- final String folderName;
- synchronized (this) {
- if( _generatedSourceFolder != null )
- return _generatedSourceFolder;
- folderName = getFolderName();
- }
- if(folderName == null)
- return null;
-
- return _aptProject.getJavaProject().getProject().getFolder( folderName );
- }
-
- /**
- * returns the name of the folder for generated source files. The name is relative
- * to the project root.
- *
- * @see #getFolder()
- * @see #isGeneratedSourceFolderConfigured()
- */
- public synchronized String getFolderName()
- {
- return _generatedSourceFolderName;
+ AptPlugin.trace("set _generatedSourceFolder to null; was " + srcFolder ); //$NON-NLS-1$
}
/**
@@ -357,78 +332,42 @@ public class GeneratedSourceFolderManager {
return outputRootPath;
}
-
+
/**
- * Configure the generated source folder according to whether APT is enabled
- * or disabled. If enabled, the folder will be created and a classpath entry
- * will be added. If disabled, the folder and classpath entry will be removed.
- * <p>
- * This should only be called on an event thread, with no locks on the project
- * or classpath.
- * @param enable
+ * Get the current generated source folder; or if it is null, return
+ * an IFolder corresponding to the current generated source folder name.
+ * This is a handle-only operation and does not have anything to do with
+ * whether the folder exists on disk.
+ * @throws IllegalArgumentException if the name is invalid (e.g., "..").
*/
- public void setEnabled(boolean enable)
- {
- if( AptPlugin.DEBUG ){
- if( enable )
- AptPlugin.trace("enabling APT for " + _aptProject.getJavaProject().getElementName()); //$NON-NLS-1$
- else
- AptPlugin.trace("disabling APT for " + _aptProject.getJavaProject().getElementName()); //$NON-NLS-1$
- }
- if( enable ) {
- final String folderName = _generatedSourceFolderName;
- if( AptPlugin.DEBUG ){
- AptPlugin.trace("configure generated source folder to be " + folderName ); //$NON-NLS-1$
- }
- configure(folderName, null);
- } else{
- final IFolder srcFolder = getFolder();
- _aptProject.projectClean(true);
- resetGeneratedSrcFolder(srcFolder, false);
+ public IFolder getFolder(){
+
+ synchronized (this) {
+ if( _generatedSourceFolder != null )
+ return _generatedSourceFolder;
}
+
+ return getFolderPreference();
}
-
+
/**
- * Configure the name of the generated source folder. If APT is enabled,
- * remove the old folder and classpath entry and create new ones. If
- * disabled, simply record the new name.
- * <p>
- * This should only be called on an event thread, with no locks on the project
- * or classpath.
- * TODO: why does this need to know the old name? Didn't we get it in the constructor?
- * @param oldName can be null if the old value is not known.
- * @param newName
+ * Get an IFolder that corresponds to the folder name preference.
+ * This has nothing to do with whether APT is enabled or disabled,
+ * nothing to do with whether the folder exists on disk; it's just
+ * a handle corresponding to a name.
+ * @return null if the IFolder could not be created, which probably
+ * means that the name is something illegal like "..".
*/
- public void changeFolderName(String oldName, String newName)
- {
- if (newName == null) {
- // Null is used to indicate this preference has
- // been removed, as the project has been deleted.
- // We do nothing
- return;
+ private IFolder getFolderPreference() {
+ final String folderName = AptConfig.getGenSrcDir(_aptProject.getJavaProject());
+ IFolder folder = null;
+ try {
+ folder = _aptProject.getJavaProject().getProject().getFolder( folderName );
}
- if (newName.equals(oldName)) {
- // No-op -- same config
- return;
+ catch (IllegalArgumentException e) {
+ // In the event that the folderName is invalid, just return null.
}
-
- final boolean aptEnabled = AptConfig.isEnabled(_aptProject.getJavaProject());
- if( AptPlugin.DEBUG )
- AptPlugin.trace("configure generated source directory new value = " + //$NON-NLS-1$
- newName +
- " old value = " + oldName + //$NON-NLS-1$
- " APT is enabled = " + aptEnabled); //$NON-NLS-1$
- if( aptEnabled )
- // If APT is enabled,
- // clean up the old cp entry, delete the old folder,
- // create the new one and update the classpath.
- configure( newName, oldName );
- else
- // If APT is not enabled, the folder should not exist
- // and there should be no entry on the classpath.
- synchronized (this) {
- _generatedSourceFolderName = newName;
- }
+ return folder;
}
/**
@@ -444,79 +383,64 @@ public class GeneratedSourceFolderManager {
{
return folder != null && folder.equals( getFolder() );
}
-
+
+ private boolean isOnClasspath(IFolder srcFolder) {
+ boolean found = false;
+ try {
+ if (ClasspathUtil.doesClasspathContainEntry(
+ _aptProject.getJavaProject(), null, srcFolder.getFullPath(), null)) {
+ found = true;
+ }
+ } catch (JavaModelException e) {
+ e.printStackTrace();
+ }
+ return found;
+ }
+
/**
- * Cleanup the classpath and schedule a job to delete the generated source folder.
- * @param recreate if <code>true</code> configure the generated source directory.
+ * Remove a folder from disk and from the classpath.
+ * @param srcFolder
*/
- private void resetGeneratedSrcFolder(final IFolder srcFolder, boolean recreate){
- // clean up the classpath first so that when we actually delete the
- // generated source folder and won't cause a classpath error.
- if( srcFolder != null ){
- try{
- ClasspathUtil.removeFromProjectClasspath( _aptProject.getJavaProject(), srcFolder, null );
- }catch(JavaModelException e){
- AptPlugin.log( e, "Error occurred deleting old generated src folder " + srcFolder.getName() ); //$NON-NLS-1$
- }
+ private void removeFolder() {
+ IFolder srcFolder = null;
+ synchronized ( this )
+ {
+ srcFolder = _generatedSourceFolder;
+ _generatedSourceFolder = null;
+ }
+ if (srcFolder == null) {
+ return;
}
- if( recreate )
- ensureGeneratedSourceFolder();
+ // Clear out the generated file maps
+ _aptProject.projectClean(false);
- // delete the generated source folder as well as
- // all of its derived ancestors that are containers only to the
- // generated source folder
- if( srcFolder != null ){
- IFolder folderToDelete = srcFolder;
- for( IContainer c = srcFolder.getParent();
- c != null && (c instanceof IFolder);
- c = c.getParent() ){
-
- try{
- // members can't be empty, there has to be at least 1.
- // will only delete the parent if it contains only the
- // folder that we want to delete.
- if( c.isDerived() && c.members().length == 1 ){
- folderToDelete = (IFolder)c;
- }
- else
- break;
- }catch(CoreException e){
- AptPlugin.log(e, "failure while accessing member of " + c.getName() ); //$NON-NLS-1$
- break;
- }
- }
- removeFolder(folderToDelete);
+ // clean up the classpath first so that when we actually delete the
+ // generated source folder we won't cause a classpath error.
+ try {
+ ClasspathUtil.removeFromProjectClasspath( _aptProject.getJavaProject(), srcFolder, null );
+ } catch (JavaModelException e) {
+ AptPlugin.log( e, "Failed to remove classpath entry for old generated src folder " + srcFolder.getName() ); //$NON-NLS-1$
}
+
+ FileSystemUtil.deleteFolder(srcFolder);
}
/**
- * Remove the specified folder from disk.
- * @param srcFolder
+ * Check whether the proposed name is permitted.
+ * @param dirString can be anything, including null.
+ * @return true if attempting to set the generated source folder to
+ * <code>dirString</code> is likely to succeed.
*/
- private void removeFolder(final IFolder srcFolder) {
- if( srcFolder != null ){
- final IWorkspaceRunnable runnable = new IWorkspaceRunnable(){
- public void run(IProgressMonitor monitor)
- {
- if( srcFolder != null ){
- try{
- srcFolder.delete(true, false, null);
- }catch(CoreException e){
- AptPlugin.log(e, "failed to delete old generated source folder " + srcFolder.getName() ); //$NON-NLS-1$
- }catch(OperationCanceledException cancel){
- AptPlugin.log(cancel, "deletion of generated source folder got cancelled"); //$NON-NLS-1$
- }
- }
- };
- };
- IWorkspace ws = _aptProject.getJavaProject().getProject().getWorkspace();
- try{
- ws.run(runnable, ws.getRoot(), IWorkspace.AVOID_UPDATE, null);
- }catch(CoreException e){
- AptPlugin.log(e, "Runnable for deleting old generated source folder " + srcFolder.getName() + " failed."); //$NON-NLS-1$ //$NON-NLS-2$
- }
+ public static boolean validate(final IJavaProject jproj, final String folderName) {
+ IFolder folder = null;
+ try {
+ folder = jproj.getProject().getFolder( folderName );
+ }
+ catch (IllegalArgumentException e) {
+ return false;
}
+ return folder != null;
}
-
+
}
diff --git a/org.eclipse.jdt.apt.core/src/org/eclipse/jdt/apt/core/internal/type/ArrayTypeImpl.java b/org.eclipse.jdt.apt.core/src/org/eclipse/jdt/apt/core/internal/type/ArrayTypeImpl.java
index 2ad0bc230d..c607657564 100644
--- a/org.eclipse.jdt.apt.core/src/org/eclipse/jdt/apt/core/internal/type/ArrayTypeImpl.java
+++ b/org.eclipse.jdt.apt.core/src/org/eclipse/jdt/apt/core/internal/type/ArrayTypeImpl.java
@@ -50,7 +50,7 @@ public class ArrayTypeImpl implements ArrayType, EclipseMirrorImpl
else{
final ITypeBinding leaf = elementType.getElementType();
final String componentKey = BindingKey.createArrayTypeBindingKey(leaf.getKey(), dimension - 1);
- componentType = _env.getTypeBinding(componentKey);
+ componentType = _env.getTypeBindingFromKey(componentKey);
if( componentType == null )
throw new IllegalStateException("unknown component type for " + _arrayBinding); //$NON-NLS-1$
}
diff --git a/org.eclipse.jdt.apt.core/src/org/eclipse/jdt/apt/core/internal/util/Factory.java b/org.eclipse.jdt.apt.core/src/org/eclipse/jdt/apt/core/internal/util/Factory.java
index a109090d51..e8bd0204bb 100644
--- a/org.eclipse.jdt.apt.core/src/org/eclipse/jdt/apt/core/internal/util/Factory.java
+++ b/org.eclipse.jdt.apt.core/src/org/eclipse/jdt/apt/core/internal/util/Factory.java
@@ -27,6 +27,7 @@ import java.util.List;
import org.eclipse.core.resources.IFile;
import org.eclipse.jdt.apt.core.internal.EclipseMirrorImpl;
import org.eclipse.jdt.apt.core.internal.declaration.ASTBasedAnnotationElementDeclarationImpl;
+import org.eclipse.jdt.apt.core.internal.declaration.ASTBasedConstructorDeclarationImpl;
import org.eclipse.jdt.apt.core.internal.declaration.ASTBasedFieldDeclarationImpl;
import org.eclipse.jdt.apt.core.internal.declaration.ASTBasedMethodDeclarationImpl;
import org.eclipse.jdt.apt.core.internal.declaration.AnnotationDeclarationImpl;
@@ -132,7 +133,12 @@ public class Factory
case ASTNode.VARIABLE_DECLARATION_FRAGMENT:
return new ASTBasedFieldDeclarationImpl( (VariableDeclarationFragment)node, file, env );
case ASTNode.METHOD_DECLARATION :
- return new ASTBasedMethodDeclarationImpl( (org.eclipse.jdt.core.dom.MethodDeclaration)node, file, env );
+ final org.eclipse.jdt.core.dom.MethodDeclaration methodDecl =
+ (org.eclipse.jdt.core.dom.MethodDeclaration)node;
+ if( methodDecl.isConstructor() )
+ return new ASTBasedConstructorDeclarationImpl(methodDecl, file, env);
+ else
+ return new ASTBasedMethodDeclarationImpl(methodDecl, file, env );
case ASTNode.ANNOTATION_TYPE_MEMBER_DECLARATION:
return new ASTBasedMethodDeclarationImpl((AnnotationTypeMemberDeclaration)node, file, env);
default :
diff --git a/org.eclipse.jdt.apt.core/src/org/eclipse/jdt/apt/core/internal/util/FileSystemUtil.java b/org.eclipse.jdt.apt.core/src/org/eclipse/jdt/apt/core/internal/util/FileSystemUtil.java
index a378c94936..04d164eb08 100644
--- a/org.eclipse.jdt.apt.core/src/org/eclipse/jdt/apt/core/internal/util/FileSystemUtil.java
+++ b/org.eclipse.jdt.apt.core/src/org/eclipse/jdt/apt/core/internal/util/FileSystemUtil.java
@@ -24,8 +24,13 @@ import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IWorkspace;
+import org.eclipse.core.resources.IWorkspaceRunnable;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.OperationCanceledException;
+import org.eclipse.jdt.apt.core.AptPlugin;
/**
* Simple utility class to encapsulate an mkdirs() that avoids a timing issue
@@ -35,6 +40,36 @@ public final class FileSystemUtil
{
private FileSystemUtil() {}
+ /**
+ * Remove the specified folder from disk, using a WorkspaceRunnable so that
+ * the job blocks until it can obtain the necessary locks.
+ * @param folder
+ */
+ public static void deleteFolder(final IFolder folder) {
+ if( folder != null ){
+ final IWorkspaceRunnable runnable = new IWorkspaceRunnable(){
+ public void run(IProgressMonitor monitor)
+ {
+ if( folder != null ){
+ try{
+ folder.delete(true, false, null);
+ }catch(CoreException e){
+ AptPlugin.log(e, "failed to delete old generated source folder " + folder.getName() ); //$NON-NLS-1$
+ }catch(OperationCanceledException cancel){
+ AptPlugin.log(cancel, "deletion of generated source folder got cancelled"); //$NON-NLS-1$
+ }
+ }
+ };
+ };
+ IWorkspace ws = ResourcesPlugin.getWorkspace();
+ try{
+ ws.run(runnable, ws.getRoot(), IWorkspace.AVOID_UPDATE, null);
+ }catch(CoreException e){
+ AptPlugin.log(e, "Runnable for deleting old generated source folder " + folder.getName() + " failed."); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+ }
+ }
+
public static void mkdirs( File parent )
{
if ( parent == null )
diff --git a/org.eclipse.jdt.apt.core/src/org/eclipse/jdt/apt/core/internal/util/TypesUtil.java b/org.eclipse.jdt.apt.core/src/org/eclipse/jdt/apt/core/internal/util/TypesUtil.java
index fb4f853165..efb0929368 100644
--- a/org.eclipse.jdt.apt.core/src/org/eclipse/jdt/apt/core/internal/util/TypesUtil.java
+++ b/org.eclipse.jdt.apt.core/src/org/eclipse/jdt/apt/core/internal/util/TypesUtil.java
@@ -86,7 +86,7 @@ public class TypesUtil implements Types
throw new IllegalArgumentException("illegal component type: " + componentType); //$NON-NLS-1$
final String bindingKey = BindingKey.createArrayTypeBindingKey(leaf.getKey(), dimension);
- final ITypeBinding arrayType = _env.getTypeBinding(bindingKey);
+ final ITypeBinding arrayType = _env.getTypeBindingFromKey(bindingKey);
if(arrayType == null)
return null;
return (ArrayType)Factory.createTypeMirror(arrayType, _env);
@@ -168,7 +168,7 @@ public class TypesUtil implements Types
"but found " + numArgs ); //$NON-NLS-1$
final String typeKey = BindingKey.createParameterizedTypeBindingKey(memberBinding.getKey(), argKeys);
- final ITypeBinding resultBinding = _env.getTypeBinding(typeKey);
+ final ITypeBinding resultBinding = _env.getTypeBindingFromKey(typeKey);
return Factory.createReferenceType(resultBinding, _env);
}
else{
@@ -275,7 +275,7 @@ public class TypesUtil implements Types
throw new IllegalArgumentException("Wildcard can only have a upper bound, a lower bound or be unbounded."); //$NON-NLS-1$
final String wildcardkey = BindingKey.createWilcardTypeBindingKey(boundKey, boundKind);
- final ITypeBinding wildcard = _env.getTypeBinding(wildcardkey);
+ final ITypeBinding wildcard = _env.getTypeBindingFromKey(wildcardkey);
return (WildcardType)Factory.createTypeMirror(wildcard, _env);
}
diff --git a/org.eclipse.jdt.apt.core/src/org/eclipse/jdt/apt/core/messages.properties b/org.eclipse.jdt.apt.core/src/org/eclipse/jdt/apt/core/messages.properties
deleted file mode 100644
index 1619830255..0000000000
--- a/org.eclipse.jdt.apt.core/src/org/eclipse/jdt/apt/core/messages.properties
+++ /dev/null
@@ -1 +0,0 @@
-AptPlugin_couldNotFindToolsDotJar=Could not find tools.jar in plugin directory: org.eclipse.jdt.apt.core will not load
diff --git a/org.eclipse.jdt.apt.core/src/org/eclipse/jdt/apt/core/util/AptConfig.java b/org.eclipse.jdt.apt.core/src/org/eclipse/jdt/apt/core/util/AptConfig.java
index 50183853c3..a4b0530538 100644
--- a/org.eclipse.jdt.apt.core/src/org/eclipse/jdt/apt/core/util/AptConfig.java
+++ b/org.eclipse.jdt.apt.core/src/org/eclipse/jdt/apt/core/util/AptConfig.java
@@ -17,6 +17,8 @@ import java.util.Map;
import java.util.Map.Entry;
import org.eclipse.core.resources.IFolder;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.ProjectScope;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
@@ -30,6 +32,7 @@ import org.eclipse.core.runtime.preferences.InstanceScope;
import org.eclipse.jdt.apt.core.AptPlugin;
import org.eclipse.jdt.apt.core.internal.AnnotationProcessorFactoryLoader;
import org.eclipse.jdt.apt.core.internal.AptProject;
+import org.eclipse.jdt.apt.core.internal.generatedfile.GeneratedSourceFolderManager;
import org.eclipse.jdt.apt.core.internal.util.FactoryPath;
import org.eclipse.jdt.apt.core.internal.util.FactoryPathUtil;
import org.eclipse.jdt.core.IClasspathEntry;
@@ -133,7 +136,7 @@ public class AptConfig {
return options;
}
- IPath workspaceRootPath = jproj.getProject().getWorkspace().getRoot().getLocation();
+ IWorkspaceRoot root = jproj.getProject().getWorkspace().getRoot();
// Add sourcepath and classpath variables
try {
@@ -151,35 +154,53 @@ public class AptConfig {
else {
classpathSB.append(File.pathSeparatorChar);
}
- classpathSB.append(entry.getPath().makeAbsolute().toOSString());
+ IPath cpPath = entry.getPath();
+
+ IResource res = root.findMember(cpPath);
+
+ // If res is null, the path is absolute (it's an external jar)
+ if (res == null) {
+ classpathSB.append(cpPath.toOSString());
+ }
+ else {
+ // It's relative
+ classpathSB.append(res.getLocation().toOSString());
+ }
}
else if (kind == IClasspathEntry.CPE_SOURCE) {
if (firstSP) {
firstSP = false;
}
else {
- sourcepathSB.append(File.separatorChar);
+ sourcepathSB.append(File.pathSeparatorChar);
}
- // Sourcepath is a bit odd -- it's workspace-relative
- IPath sourcepath = entry.getPath();
- sourcepathSB.append(workspaceRootPath.append(sourcepath).toOSString());
+
+ sourcepathSB.append(root.findMember(entry.getPath()).getLocation().toOSString());
}
}
// if you add options here, also add them in isAutomaticProcessorOption(),
// and document them in docs/reference/automatic_processor_options.html.
// Classpath and sourcepath
- options.put("-classpath",classpathSB.toString()); //$NON-NLS-1$
+ options.put("-classpath",classpathSB.toString()); //$NON-NLS-1$
options.put("-sourcepath", sourcepathSB.toString()); //$NON-NLS-1$
// Get absolute path for generated source dir
IFolder genSrcDir = jproj.getProject().getFolder(getGenSrcDir(jproj));
- options.put("-s", genSrcDir.getRawLocation().toOSString()); //$NON-NLS-1$
+ String genSrcDirString = genSrcDir.getRawLocation().toOSString();
+ options.put("-s", genSrcDirString); //$NON-NLS-1$
// Absolute path for bin dir as well
IPath binPath = jproj.getOutputLocation();
- IPath binDir = workspaceRootPath.append(binPath);
- options.put("-d", binDir.toOSString()); //$NON-NLS-1$
+ IResource binPathResource = root.findMember(binPath);
+ String binDirString;
+ if (binPathResource != null) {
+ binDirString = root.findMember(binPath).getLocation().toOSString();
+ }
+ else {
+ binDirString = binPath.toOSString();
+ }
+ options.put("-d", binDirString); //$NON-NLS-1$
String target = jproj.getOption(JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM, true);
options.put("-target", target); //$NON-NLS-1$
@@ -621,19 +642,19 @@ public class AptConfig {
}
public static String getGenSrcDir(IJavaProject jproject) {
- String genSrcDir = getString(jproject, AptPreferenceConstants.APT_GENSRCDIR);
- if (genSrcDir == null) {
- throw new IllegalStateException("Generated Source Directory was null."); //$NON-NLS-1$
- }
- return genSrcDir;
+ return getString(jproject, AptPreferenceConstants.APT_GENSRCDIR);
}
public static void setGenSrcDir(IJavaProject jproject, String dirString) {
- if (dirString == null) {
- throw new IllegalArgumentException("Cannot set the Generated Source Directory to null"); //$NON-NLS-1$
+ if (!GeneratedSourceFolderManager.validate(jproject, dirString)) {
+ throw new IllegalArgumentException("Illegal name for generated source folder: " + dirString); //$NON-NLS-1$
}
setString(jproject, AptPreferenceConstants.APT_GENSRCDIR, dirString);
}
+
+ public static boolean validateGenSrcDir(IJavaProject jproject, String dirName) {
+ return GeneratedSourceFolderManager.validate(jproject, dirName);
+ }
private static void setBoolean(IJavaProject jproject, String optionName, boolean value) {
IScopeContext context = (null != jproject) ?
@@ -642,9 +663,9 @@ public class AptConfig {
// get old val as a String, so it can be null if setting doesn't exist yet
String oldValue = node.get(optionName, null);
node.putBoolean(optionName, value);
- if (jproject != null) {
+ if (jproject != null && oldValue == null || (value != Boolean.parseBoolean(oldValue))) {
AptProject aproj = AptPlugin.getAptProject(jproject);
- aproj.handlePreferenceChange(optionName, oldValue, Boolean.toString(value));
+ aproj.preferenceChanged(optionName);
}
flushPreference(optionName, node);
}
@@ -655,9 +676,9 @@ public class AptConfig {
IEclipsePreferences node = context.getNode(AptPlugin.PLUGIN_ID);
String oldValue = node.get(optionName, null);
node.put(optionName, value);
- if (jproject != null) {
+ if (jproject != null && !value.equals(oldValue)) {
AptProject aproj = AptPlugin.getAptProject(jproject);
- aproj.handlePreferenceChange(optionName, oldValue, value);
+ aproj.preferenceChanged(optionName);
}
flushPreference(optionName, node);
}
diff --git a/org.eclipse.jdt.apt.tests/plugin.xml b/org.eclipse.jdt.apt.tests/plugin.xml
index a9e8928145..546ac06473 100644
--- a/org.eclipse.jdt.apt.tests/plugin.xml
+++ b/org.eclipse.jdt.apt.tests/plugin.xml
@@ -59,6 +59,9 @@
<factory
class="org.eclipse.jdt.apt.tests.annotations.apitest.APIAnnotationProcessorFactory">
</factory>
+ <factory
+ class="org.eclipse.jdt.apt.tests.annotations.mirrortest.ASTBasedMirrorDeclarationProcessorFactory">
+ </factory>
</factories>
</extension>
diff --git a/org.eclipse.jdt.apt.tests/src/org/eclipse/jdt/apt/tests/MirrorDeclarationTests.java b/org.eclipse.jdt.apt.tests/src/org/eclipse/jdt/apt/tests/MirrorDeclarationTests.java
index 1575d72698..af43cafbac 100644
--- a/org.eclipse.jdt.apt.tests/src/org/eclipse/jdt/apt/tests/MirrorDeclarationTests.java
+++ b/org.eclipse.jdt.apt.tests/src/org/eclipse/jdt/apt/tests/MirrorDeclarationTests.java
@@ -19,6 +19,7 @@ import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.IPath;
import org.eclipse.jdt.apt.tests.annotations.ProcessorTestStatus;
import org.eclipse.jdt.apt.tests.annotations.mirrortest.MirrorDeclarationCodeExample;
+import org.eclipse.jdt.core.tests.builder.Problem;
public class MirrorDeclarationTests extends APTTestBase {
@@ -111,4 +112,99 @@ public class MirrorDeclarationTests extends APTTestBase {
fullBuild( project.getFullPath() );
expectingNoProblems();
}
+
+ /**
+ * Test AST based mirror implementation and binding based mirror implementation.
+ * Specifically,
+ * (i) method declaration with unresolvable return type.
+ * (ii) constructor declaration with unresolvable parameter
+ * (iii) field declaration with unresolvable type.
+ *
+ * This test focus on declarations from file in context.
+ *
+ * @throws Exception
+ */
+ public void testUnresolvableDeclarations0()
+ throws Exception
+ {
+ IProject project = env.getProject( getProjectName() );
+ IPath srcRoot = getSourcePath();
+ String declAnno =
+ "package test;\n" +
+ "public @interface DeclarationAnno{}";
+
+ env.addClass(srcRoot, "test", "DeclarationAnno", declAnno);
+
+ String codeFoo =
+ "package test;\n" +
+ "@DeclarationAnno\n" +
+ "public class Foo {\n" +
+ " int field0;\n " +
+ " UnknownType field1;\n " +
+ " public Foo(UnknownType type){} \n" +
+ " public void voidMethod(){} \n " +
+ " public UnknownType getType(){}\n " +
+ " public class Inner{} \n" +
+ "}";
+
+ final IPath fooPath = env.addClass(srcRoot, "test", "Foo", codeFoo);
+ fullBuild( project.getFullPath() );
+
+ expectingOnlySpecificProblemsFor(fooPath, new Problem[]{
+ new Problem("", "UnknownType cannot be resolved to a type", fooPath),
+ new Problem("", "UnknownType cannot be resolved to a type", fooPath),
+ new Problem("", "UnknownType cannot be resolved to a type", fooPath)}
+ );
+ }
+
+ /**
+ * Test AST based mirror implementation and binding based mirror implementation.
+ * Specifically,
+ * (i) method declaration with unresolvable return type.
+ * (ii) constructor declaration with unresolvable parameter
+ * (iii) field declaration with unresolvable type.
+ *
+ * This test focus on declarations from file outside of processor
+ * environment context.
+ *
+ * @throws Exception
+ */
+ public void testUnresolvableDeclarations1()
+ throws Exception
+ {
+ IProject project = env.getProject( getProjectName() );
+ IPath srcRoot = getSourcePath();
+ String declAnno =
+ "package test;\n" +
+ "public @interface DeclarationAnno{}";
+
+ env.addClass(srcRoot, "test", "DeclarationAnno", declAnno);
+
+ String codeBar =
+ "package test;\n" +
+ "@DeclarationAnno\n" +
+ "public class Bar {}";
+ env.addClass(srcRoot, "test", "Bar", codeBar);
+
+ String codeFoo =
+ "package test;\n" +
+ "@DeclarationAnno\n" +
+ "public class Foo {\n" +
+ " int field0;\n " +
+ " UnknownType field1;\n " +
+ " public Foo(UnknownType type){} \n" +
+ " public void voidMethod(){} \n " +
+ " public UnknownType getType(){}\n " +
+ " public class Inner{} \n" +
+ "}";
+
+ final IPath fooPath = env.addClass(srcRoot, "test", "Foo", codeFoo);
+
+ fullBuild( project.getFullPath() );
+ expectingOnlySpecificProblemsFor(fooPath, new Problem[]{
+ new Problem("", "UnknownType cannot be resolved to a type", fooPath),
+ new Problem("", "UnknownType cannot be resolved to a type", fooPath),
+ new Problem("", "UnknownType cannot be resolved to a type", fooPath)}
+ );
+ }
}
diff --git a/org.eclipse.jdt.apt.tests/src/org/eclipse/jdt/apt/tests/annotations/BaseProcessor.java b/org.eclipse.jdt.apt.tests/src/org/eclipse/jdt/apt/tests/annotations/BaseProcessor.java
index 6535e74add..fd1440af08 100644
--- a/org.eclipse.jdt.apt.tests/src/org/eclipse/jdt/apt/tests/annotations/BaseProcessor.java
+++ b/org.eclipse.jdt.apt.tests/src/org/eclipse/jdt/apt/tests/annotations/BaseProcessor.java
@@ -13,6 +13,7 @@ package org.eclipse.jdt.apt.tests.annotations;
import com.sun.mirror.apt.AnnotationProcessor;
import com.sun.mirror.apt.AnnotationProcessorEnvironment;
+import com.sun.mirror.apt.Messager;
public abstract class BaseProcessor implements AnnotationProcessor {
@@ -21,5 +22,33 @@ public abstract class BaseProcessor implements AnnotationProcessor {
public BaseProcessor(final AnnotationProcessorEnvironment env) {
_env = env;
}
-
+
+ protected void assertEqual(final int expected, final int actual, final String message){
+ if(expected != actual){
+ final Messager msgr = _env.getMessager();
+ msgr.printError(message + " expected: " + expected + " actual: " + actual );
+ }
+ }
+
+ protected void assertEqual(final String expected, final String actual, final String message){
+ if( expected == null ){
+ final Messager msgr = _env.getMessager();
+ msgr.printError(message + " actual: " + actual );
+ }
+ else if( actual == null ){
+ final Messager msgr = _env.getMessager();
+ msgr.printError(message + "expected " + expected );
+ }
+ else if( !expected.equals(actual) ){
+ final Messager msgr = _env.getMessager();
+ msgr.printError(message + " expected: " + expected + " actual: " + actual );
+ }
+ }
+
+ protected void assertNonNull(final Object obj, final String message){
+ if( obj == null ){
+ final Messager msgr = _env.getMessager();
+ msgr.printError(message);
+ }
+ }
}
diff --git a/org.eclipse.jdt.apt.tests/src/org/eclipse/jdt/apt/tests/annotations/mirrortest/ASTBasedMirrorDeclarationProcessorFactory.java b/org.eclipse.jdt.apt.tests/src/org/eclipse/jdt/apt/tests/annotations/mirrortest/ASTBasedMirrorDeclarationProcessorFactory.java
new file mode 100644
index 0000000000..db8e4c1532
--- /dev/null
+++ b/org.eclipse.jdt.apt.tests/src/org/eclipse/jdt/apt/tests/annotations/mirrortest/ASTBasedMirrorDeclarationProcessorFactory.java
@@ -0,0 +1,122 @@
+package org.eclipse.jdt.apt.tests.annotations.mirrortest;
+
+import java.util.Collection;
+import java.util.Set;
+
+import org.eclipse.jdt.apt.tests.annotations.BaseFactory;
+import org.eclipse.jdt.apt.tests.annotations.BaseProcessor;
+
+import com.sun.mirror.apt.AnnotationProcessor;
+import com.sun.mirror.apt.AnnotationProcessorEnvironment;
+import com.sun.mirror.declaration.AnnotationTypeDeclaration;
+import com.sun.mirror.declaration.ClassDeclaration;
+import com.sun.mirror.declaration.ConstructorDeclaration;
+import com.sun.mirror.declaration.FieldDeclaration;
+import com.sun.mirror.declaration.MethodDeclaration;
+import com.sun.mirror.declaration.TypeDeclaration;
+
+public class ASTBasedMirrorDeclarationProcessorFactory
+ extends BaseFactory
+{
+ public ASTBasedMirrorDeclarationProcessorFactory(){
+ super("test.DeclarationAnno");
+ }
+
+ public AnnotationProcessor getProcessorFor(
+ Set<AnnotationTypeDeclaration> arg0,
+ AnnotationProcessorEnvironment env) {
+ return new ASTBasedMirrorDeclarationProcessor(env);
+ }
+
+ public static final class ASTBasedMirrorDeclarationProcessor
+ extends BaseProcessor{
+
+ public ASTBasedMirrorDeclarationProcessor(AnnotationProcessorEnvironment env){
+ super(env);
+ }
+ public void process() {
+ final Collection<TypeDeclaration> typeDecls = _env.getTypeDeclarations();
+ boolean done = false;
+ for( TypeDeclaration typeDecl : typeDecls ){
+ if(typeDecl instanceof ClassDeclaration ){
+ examineClass( (ClassDeclaration)typeDecl );
+ if( typeDecl.getQualifiedName().equals("test.Foo") )
+ done = true;
+ }
+ }
+ // if the current file does not contain "test.Foo",
+ // look for it by name and run the same tests.
+ if( !done ){
+ final ClassDeclaration fooDecl = (ClassDeclaration)_env.getTypeDeclaration("test.Foo");
+ examineClass(fooDecl);
+ final ClassDeclaration innerTypeDecl = (ClassDeclaration)_env.getTypeDeclaration("test.Foo$Inner");
+ examineClass(innerTypeDecl);
+ }
+ }
+
+ private void examineClass(ClassDeclaration typeDecl ){
+
+ assertNonNull(typeDecl, "missing type declaration");
+ if( typeDecl != null ){
+ final String typename = typeDecl.getSimpleName();
+ if(typename.equals("Foo")){
+ final Collection<? extends MethodDeclaration> methods =
+ typeDecl.getMethods();
+ assertEqual(2, methods.size(), "number of methods do not match ");
+ for(MethodDeclaration method : methods ){
+ final String name = method.getSimpleName();
+ if( name.equals("getType") ){
+ final String methodString = method.toString();
+ final String expectedString = "UnknownType getType()";
+ assertEqual(expectedString, methodString, "signature mismatch");
+ }
+ else if( name.equals("voidMethod")){
+ final String methodString = method.toString();
+ final String expectedString = "void voidMethod()";
+ assertEqual(expectedString, methodString, "signature mismatch");
+ }
+ else{
+ assertEqual(null, method.toString(), "unexpected method");
+ }
+ }
+
+ final Collection<ConstructorDeclaration> constructors =
+ typeDecl.getConstructors();
+ assertEqual(1, constructors.size(), "number of constructors do not match");
+ for( ConstructorDeclaration constructor : constructors ){
+ final String constructorString = constructor.toString();
+ final String expectedString = " Foo(type)";
+ assertEqual(expectedString, constructorString, "signature mismatch");
+ }
+ final Collection<FieldDeclaration> fields =
+ typeDecl.getFields();
+ assertEqual(2, fields.size(), "number of fields do not match");
+ for( FieldDeclaration field : fields ){
+ final String name = field.getSimpleName();
+ if( "field0".equals(name) || "field1".equals(name) ){
+ continue;
+ }
+ assertEqual(null, name, "unexpected field");
+ }
+ }
+ else if(typename.equals("Inner")){
+ final Collection<? extends MethodDeclaration> methods =
+ typeDecl.getMethods();
+ assertEqual(0, methods.size(), "number of methods do not match ");
+
+ final Collection<ConstructorDeclaration> constructors =
+ typeDecl.getConstructors();
+ assertEqual(1, constructors.size(), "number of constructors do not match");
+ for( ConstructorDeclaration constructor : constructors ){
+ final String constructorString = constructor.toString();
+ final String expectedString = "Inner()";
+ assertEqual(expectedString, constructorString, "signature mismatch");
+ }
+ final Collection<FieldDeclaration> fields =
+ typeDecl.getFields();
+ assertEqual(0, fields.size(), "number of fields do not match");
+ }
+ }
+ }
+ }
+}
diff --git a/org.eclipse.jdt.apt.ui/scripts/exportplugin.xml b/org.eclipse.jdt.apt.ui/scripts/exportplugin.xml
index 4313f06548..7ed0bfe024 100644
--- a/org.eclipse.jdt.apt.ui/scripts/exportplugin.xml
+++ b/org.eclipse.jdt.apt.ui/scripts/exportplugin.xml
@@ -22,7 +22,7 @@
<target name="export plug-in [_1.0.0]">
<antcall target="zz_internal_export">
- <param name="plugin_version" value="3.1.1.apt02"/>
+ <param name="plugin_version" value="3.1.1.apt03"/>
</antcall>
</target>
diff --git a/org.eclipse.jdt.apt.ui/src/org/eclipse/jdt/apt/ui/internal/preferences/AptConfigurationBlock.java b/org.eclipse.jdt.apt.ui/src/org/eclipse/jdt/apt/ui/internal/preferences/AptConfigurationBlock.java
index 3e0206c0c5..1a52069517 100644
--- a/org.eclipse.jdt.apt.ui/src/org/eclipse/jdt/apt/ui/internal/preferences/AptConfigurationBlock.java
+++ b/org.eclipse.jdt.apt.ui/src/org/eclipse/jdt/apt/ui/internal/preferences/AptConfigurationBlock.java
@@ -20,7 +20,6 @@ import java.util.Map;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.IStatus;
-import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.preferences.IScopeContext;
import org.eclipse.jdt.apt.core.AptPlugin;
import org.eclipse.jdt.apt.core.util.AptConfig;
@@ -326,13 +325,11 @@ public class AptConfigurationBlock extends BaseConfigurationBlock {
elements = getListElements();
}
saveProcessorOptions(elements);
- fAptProject.handlePreferenceChange(
- AptPreferenceConstants.APT_GENSRCDIR, fOriginalGenSrcDir, fGenSrcDirField.getText());
- fAptProject.handlePreferenceChange(
- AptPreferenceConstants.APT_ENABLED,
- Boolean.toString(fOriginalAptEnabled),
- Boolean.toString(fAptEnabledField.isSelected()));
super.saveSettings();
+ if (!fOriginalGenSrcDir.equals(fGenSrcDirField.getText()))
+ fAptProject.preferenceChanged(AptPreferenceConstants.APT_GENSRCDIR);
+ if (fOriginalAptEnabled != fAptEnabledField.isSelected())
+ fAptProject.preferenceChanged(AptPreferenceConstants.APT_ENABLED);
}
/**
@@ -383,20 +380,10 @@ public class AptConfigurationBlock extends BaseConfigurationBlock {
* @return
*/
private IStatus validateGenSrcDir() {
- // TODO: this check should be delegated to a validation routine in apt.core.
String dirName = fGenSrcDirField.getText();
- Path path = null;
- if (dirName != null) {
- path= new Path(dirName);
- }
- if (path == null ||
- path.isAbsolute() ||
- path.isEmpty() ||
- !path.isValidPath(dirName) ||
- !dirName.trim().equals(dirName)) {
+ if (!AptConfig.validateGenSrcDir(fJProj, dirName)) {
return new StatusInfo(IStatus.ERROR, Messages.AptConfigurationBlock_genSrcDirMustBeValidRelativePath);
}
- // TODO: how can we tell whether dirName points to a "normal" src directory?
return new StatusInfo();
}

Back to the top